@kaspernj/api-maker 1.0.353 → 1.0.355
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 +3 -24
- package/src/bootstrap/input.jsx +5 -4
- package/src/collection-loader.jsx +1 -3
- package/src/inputs/input.jsx +12 -12
- package/src/inputs/money.jsx +19 -10
- package/src/super-admin/model-class-table.jsx +1 -0
- package/src/table/model-row.jsx +4 -3
- package/src/table/select-calculator.mjs +3 -1
- package/src/table/settings/index.jsx +1 -1
- package/src/table/table-settings.js +1 -1
- package/src/table/table.jsx +77 -87
- package/src/table/use-breakpoint.mjs +44 -0
- package/src/table/with-breakpoint.jsx +6 -45
- package/src/table/worker-plugins-check-all-checkbox.jsx +4 -1
- package/src/table/worker-plugins-checkbox.jsx +19 -11
- package/src/use-collection.mjs +12 -3
package/package.json
CHANGED
|
@@ -1,22 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"babel": {
|
|
3
|
-
"presets": [
|
|
4
|
-
[
|
|
5
|
-
"@babel/preset-env",
|
|
6
|
-
{
|
|
7
|
-
"targets": {
|
|
8
|
-
"node": "current"
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
],
|
|
12
|
-
"@babel/preset-react"
|
|
13
|
-
],
|
|
14
|
-
"plugins": [
|
|
15
|
-
"@babel/plugin-proposal-class-properties"
|
|
16
|
-
]
|
|
17
|
-
},
|
|
18
2
|
"name": "@kaspernj/api-maker",
|
|
19
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.355",
|
|
20
4
|
"type": "module",
|
|
21
5
|
"description": "",
|
|
22
6
|
"main": "index.js",
|
|
@@ -36,7 +20,6 @@
|
|
|
36
20
|
"test": "node --experimental-vm-modules ./node_modules/.bin/jest"
|
|
37
21
|
},
|
|
38
22
|
"dependencies": {
|
|
39
|
-
"@rails/actioncable": ">= 6.1.0",
|
|
40
23
|
"clone-deep": ">= 4.0.1",
|
|
41
24
|
"debounce": ">= 2.0.0",
|
|
42
25
|
"diggerize": ">= 1.0.5",
|
|
@@ -52,17 +35,13 @@
|
|
|
52
35
|
"on-location-changed": ">= 1.0.10",
|
|
53
36
|
"qs": ">= 6.9.3",
|
|
54
37
|
"replaceall": ">= 0.1.6",
|
|
55
|
-
"set-state-compare": "
|
|
38
|
+
"set-state-compare": "^1.0.41",
|
|
56
39
|
"spark-md5": "^3.0.2",
|
|
57
40
|
"strftime": ">= 0.10.0",
|
|
58
41
|
"uniqunize": "^1.0.1",
|
|
42
|
+
"use-did-mount": "^1.0.3",
|
|
59
43
|
"wake-event": ">= 0.0.1"
|
|
60
44
|
},
|
|
61
|
-
"peerDependencies": {
|
|
62
|
-
"prop-types": "^15.7.2",
|
|
63
|
-
"prop-types-exact": ">= 1.2.0",
|
|
64
|
-
"stacktrace-parser": ">= 0.1.9"
|
|
65
|
-
},
|
|
66
45
|
"devDependencies": {
|
|
67
46
|
"@babel/eslint-parser": "^7.16.3",
|
|
68
47
|
"@babel/preset-env": "^7.12.11",
|
package/src/bootstrap/input.jsx
CHANGED
|
@@ -5,8 +5,9 @@ import InvalidFeedback from "./invalid-feedback"
|
|
|
5
5
|
import Money from "../inputs/money"
|
|
6
6
|
import PropTypes from "prop-types"
|
|
7
7
|
import React from "react"
|
|
8
|
+
import {shapeComponent, ShapeComponent} from "set-state-compare/src/shape-component.js"
|
|
8
9
|
|
|
9
|
-
class ApiMakerBootstrapInput extends
|
|
10
|
+
const ApiMakerBootstrapInput = shapeComponent(class ApiMakerBootstrapInput extends ShapeComponent {
|
|
10
11
|
static propTypes = {
|
|
11
12
|
append: PropTypes.node,
|
|
12
13
|
appendText: PropTypes.node,
|
|
@@ -58,7 +59,7 @@ class ApiMakerBootstrapInput extends React.PureComponent {
|
|
|
58
59
|
const {errors} = digs(wrapperOpts, "errors")
|
|
59
60
|
|
|
60
61
|
return (
|
|
61
|
-
<div className={this.wrapperClassName()} ref=
|
|
62
|
+
<div className={this.wrapperClassName()} ref={this.props.wrapperRef}>
|
|
62
63
|
{wrapperOpts.label &&
|
|
63
64
|
<label className={this.labelClassName()} htmlFor={inputProps.id}>
|
|
64
65
|
{wrapperOpts.label}
|
|
@@ -73,7 +74,7 @@ class ApiMakerBootstrapInput extends React.PureComponent {
|
|
|
73
74
|
<Money
|
|
74
75
|
name={inputProps.name}
|
|
75
76
|
className={this.inputClassName()}
|
|
76
|
-
ref=
|
|
77
|
+
ref={this.props.moneyRef}
|
|
77
78
|
{...this.moneyProps()}
|
|
78
79
|
/>
|
|
79
80
|
}
|
|
@@ -166,6 +167,6 @@ class ApiMakerBootstrapInput extends React.PureComponent {
|
|
|
166
167
|
|
|
167
168
|
return classNames.join(" ")
|
|
168
169
|
}
|
|
169
|
-
}
|
|
170
|
+
})
|
|
170
171
|
|
|
171
172
|
export default inputWrapper(ApiMakerBootstrapInput)
|
|
@@ -31,9 +31,7 @@ const CollectionLoader = ({component, ...restProps}) => {
|
|
|
31
31
|
s.updateMeta({component, useCollectionResult})
|
|
32
32
|
|
|
33
33
|
useEffect(() => {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
componentShape.set(s.m.useCollectionResult)
|
|
34
|
+
s.m.component.setState(s.m.useCollectionResult)
|
|
37
35
|
}, cacheParts)
|
|
38
36
|
|
|
39
37
|
return null
|
package/src/inputs/input.jsx
CHANGED
|
@@ -4,11 +4,12 @@ import EventUpdated from "../event-updated"
|
|
|
4
4
|
import inputWrapper from "./input-wrapper"
|
|
5
5
|
import Money from "./money"
|
|
6
6
|
import PropTypes from "prop-types"
|
|
7
|
-
import React from "react"
|
|
7
|
+
import React, {useRef} from "react"
|
|
8
8
|
import replaceall from "replaceall"
|
|
9
|
+
import {shapeComponent, ShapeComponent} from "set-state-compare/src/shape-component.js"
|
|
9
10
|
import strftime from "strftime"
|
|
10
11
|
|
|
11
|
-
class ApiMakerInputsInput extends
|
|
12
|
+
const ApiMakerInputsInput = shapeComponent(class ApiMakerInputsInput extends ShapeComponent {
|
|
12
13
|
static defaultProps = {
|
|
13
14
|
autoRefresh: false,
|
|
14
15
|
autoSubmit: false,
|
|
@@ -30,9 +31,12 @@ class ApiMakerInputsInput extends React.PureComponent {
|
|
|
30
31
|
type: PropTypes.string
|
|
31
32
|
}
|
|
32
33
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
setup() {
|
|
35
|
+
this.visibleInputRef = useRef()
|
|
36
|
+
|
|
37
|
+
this.useStates({
|
|
38
|
+
blankInputName: digg(this, "props", "inputProps", "type") == "file"
|
|
39
|
+
})
|
|
36
40
|
}
|
|
37
41
|
|
|
38
42
|
render () {
|
|
@@ -132,9 +136,7 @@ class ApiMakerInputsInput extends React.PureComponent {
|
|
|
132
136
|
return value
|
|
133
137
|
}
|
|
134
138
|
|
|
135
|
-
autoSubmit = () => {
|
|
136
|
-
new AutoSubmit({component: this}).autoSubmit()
|
|
137
|
-
}
|
|
139
|
+
autoSubmit = () => new AutoSubmit({component: this}).autoSubmit()
|
|
138
140
|
|
|
139
141
|
formatValue (value) {
|
|
140
142
|
const {formatValue, type} = this.props
|
|
@@ -180,9 +182,7 @@ class ApiMakerInputsInput extends React.PureComponent {
|
|
|
180
182
|
return this.props.inputProps.name
|
|
181
183
|
}
|
|
182
184
|
|
|
183
|
-
inputReference()
|
|
184
|
-
return digg(this, "props", "inputProps", "ref")
|
|
185
|
-
}
|
|
185
|
+
inputReference = () => digg(this, "props", "inputProps", "ref")
|
|
186
186
|
|
|
187
187
|
onModelUpdated = (args) => {
|
|
188
188
|
const inputRef = this.inputReference()
|
|
@@ -229,7 +229,7 @@ class ApiMakerInputsInput extends React.PureComponent {
|
|
|
229
229
|
if (this.props.inputProps.type == "file" && value == "")
|
|
230
230
|
return true
|
|
231
231
|
}
|
|
232
|
-
}
|
|
232
|
+
})
|
|
233
233
|
|
|
234
234
|
export {ApiMakerInputsInput as Input}
|
|
235
235
|
export default inputWrapper(ApiMakerInputsInput)
|
package/src/inputs/money.jsx
CHANGED
|
@@ -6,9 +6,10 @@ import * as inflection from "inflection"
|
|
|
6
6
|
import MoneyFormatter from "../money-formatter"
|
|
7
7
|
import PropTypes from "prop-types"
|
|
8
8
|
import PropTypesExact from "prop-types-exact"
|
|
9
|
-
import React from "react"
|
|
9
|
+
import React, {useRef} from "react"
|
|
10
|
+
import {shapeComponent, ShapeComponent} from "set-state-compare/src/shape-component.js"
|
|
10
11
|
|
|
11
|
-
export default class ApiMakerInputsMoney extends
|
|
12
|
+
export default shapeComponent(class ApiMakerInputsMoney extends ShapeComponent {
|
|
12
13
|
static defaultProps = {
|
|
13
14
|
disabled: false,
|
|
14
15
|
showCurrencyOptions: true
|
|
@@ -20,6 +21,7 @@ export default class ApiMakerInputsMoney extends React.PureComponent {
|
|
|
20
21
|
className: PropTypes.string,
|
|
21
22
|
currenciesCollection: PropTypes.array,
|
|
22
23
|
currencyName: PropTypes.string,
|
|
24
|
+
currencyRef: PropTypes.object,
|
|
23
25
|
defaultValue: PropTypes.object,
|
|
24
26
|
disabled: PropTypes.bool.isRequired,
|
|
25
27
|
id: PropTypes.string,
|
|
@@ -31,10 +33,17 @@ export default class ApiMakerInputsMoney extends React.PureComponent {
|
|
|
31
33
|
placeholder: PropTypes.node,
|
|
32
34
|
showCurrencyOptions: PropTypes.bool,
|
|
33
35
|
small: PropTypes.bool,
|
|
34
|
-
type: PropTypes.string
|
|
36
|
+
type: PropTypes.string,
|
|
37
|
+
wholeRef: PropTypes.object
|
|
35
38
|
})
|
|
36
39
|
|
|
37
|
-
|
|
40
|
+
setup() {
|
|
41
|
+
this.inputRef = useRef()
|
|
42
|
+
this.currencyRefBackup = useRef()
|
|
43
|
+
this.currencyRef = this.props.currencyRef || this.currencyRefBackup
|
|
44
|
+
this.wholeRefBackup = useRef()
|
|
45
|
+
this.wholeRef = this.props.wholeRef || this.wholeRefBackup
|
|
46
|
+
}
|
|
38
47
|
|
|
39
48
|
getInputRef () {
|
|
40
49
|
return this.props.inputRef || this.inputRef
|
|
@@ -58,7 +67,7 @@ export default class ApiMakerInputsMoney extends React.PureComponent {
|
|
|
58
67
|
onChange={digg(this, "setCents")}
|
|
59
68
|
onKeyUp={digg(this, "setCents")}
|
|
60
69
|
placeholder={this.props.placeholder}
|
|
61
|
-
ref=
|
|
70
|
+
ref={this.wholeRef}
|
|
62
71
|
type="text"
|
|
63
72
|
/>
|
|
64
73
|
{showCurrencyOptions &&
|
|
@@ -69,7 +78,7 @@ export default class ApiMakerInputsMoney extends React.PureComponent {
|
|
|
69
78
|
id={this.inputCurrencyId()}
|
|
70
79
|
name={this.inputCurrencyName()}
|
|
71
80
|
onChange={digg(this, "onCurrencyChanged")}
|
|
72
|
-
ref=
|
|
81
|
+
ref={this.currencyRef}
|
|
73
82
|
>
|
|
74
83
|
<option></option>
|
|
75
84
|
{currenciesCollection.map((option) => (
|
|
@@ -149,19 +158,19 @@ export default class ApiMakerInputsMoney extends React.PureComponent {
|
|
|
149
158
|
const inputElement = this.getInputRef().current
|
|
150
159
|
|
|
151
160
|
if (!inputElement.value && inputElement.value == "") {
|
|
152
|
-
this.
|
|
161
|
+
this.wholeRef.current.value = ""
|
|
153
162
|
} else {
|
|
154
163
|
const cents = parseFloat(inputElement.value)
|
|
155
164
|
const formatted = MoneyFormatter.fromMoney({amount: cents, currency: this.inputCurrencyValue()}, {decimals: 2, excludeCurrency: true}).toString()
|
|
156
165
|
|
|
157
|
-
this.
|
|
166
|
+
this.wholeRef.current.value = formatted
|
|
158
167
|
}
|
|
159
168
|
}
|
|
160
169
|
|
|
161
170
|
setCents = () => {
|
|
162
171
|
const inputElement = this.getInputRef().current
|
|
163
172
|
|
|
164
|
-
let whole = MoneyFormatter.stringToFloat(this.
|
|
173
|
+
let whole = MoneyFormatter.stringToFloat(this.wholeRef.current.value)
|
|
165
174
|
let cents = parseInt(whole * 100, 10)
|
|
166
175
|
let oldCents = parseInt(inputElement.value, 10)
|
|
167
176
|
|
|
@@ -174,4 +183,4 @@ export default class ApiMakerInputsMoney extends React.PureComponent {
|
|
|
174
183
|
if (this.props.onChange && oldCents != cents)
|
|
175
184
|
this.props.onChange()
|
|
176
185
|
}
|
|
177
|
-
}
|
|
186
|
+
})
|
package/src/table/model-row.jsx
CHANGED
|
@@ -6,10 +6,11 @@ import * as inflection from "inflection"
|
|
|
6
6
|
import Link from "../link"
|
|
7
7
|
import MoneyFormatter from "../money-formatter"
|
|
8
8
|
import PropTypes from "prop-types"
|
|
9
|
+
import {shapeComponent, ShapeComponent} from "set-state-compare/src/shape-component"
|
|
9
10
|
|
|
10
11
|
const WorkerPluginsCheckbox = React.lazy(() => import("./worker-plugins-checkbox"))
|
|
11
12
|
|
|
12
|
-
export default class ApiMakerBootStrapLiveTableModelRow extends
|
|
13
|
+
export default shapeComponent(class ApiMakerBootStrapLiveTableModelRow extends ShapeComponent {
|
|
13
14
|
static propTypes = {
|
|
14
15
|
cacheKey: PropTypes.string.isRequired,
|
|
15
16
|
model: PropTypes.object.isRequired,
|
|
@@ -22,7 +23,7 @@ export default class ApiMakerBootStrapLiveTableModelRow extends React.PureCompon
|
|
|
22
23
|
const {model} = digs(this.props, "model")
|
|
23
24
|
const {modelClass, workplace} = digs(this.props.liveTable.props, "modelClass", "workplace")
|
|
24
25
|
const {actionsContent, columnsContent, destroyEnabled, editModelPath, viewModelPath} = digg(this, "props", "liveTable", "props")
|
|
25
|
-
const {columns, currentWorkplace} = digg(this, "props", "liveTable", "
|
|
26
|
+
const {columns, currentWorkplace} = digg(this, "props", "liveTable", "state")
|
|
26
27
|
|
|
27
28
|
this.modelCallbackArgs = this._modelCallbackArgs() // 'model' can change so this needs to be re-cached for every render
|
|
28
29
|
|
|
@@ -187,4 +188,4 @@ export default class ApiMakerBootStrapLiveTableModelRow extends React.PureCompon
|
|
|
187
188
|
throw new Error(`Unhandled type: ${apiMakerType}`)
|
|
188
189
|
}
|
|
189
190
|
}
|
|
190
|
-
}
|
|
191
|
+
})
|
|
@@ -10,7 +10,9 @@ class SelectCalculator {
|
|
|
10
10
|
selects() {
|
|
11
11
|
const {modelClass} = digs(this.table.props, "modelClass")
|
|
12
12
|
const select = this.table.props.select || {}
|
|
13
|
-
const {preparedColumns} = digs(this.table.
|
|
13
|
+
const {preparedColumns} = digs(this.table.state, "preparedColumns")
|
|
14
|
+
|
|
15
|
+
console.log({preparedColumns})
|
|
14
16
|
|
|
15
17
|
|
|
16
18
|
// Ensure the primary key column is loader for the primary model class
|
|
@@ -97,7 +97,7 @@ export default class ApiMakerTableSettings extends React.PureComponent {
|
|
|
97
97
|
|
|
98
98
|
render() {
|
|
99
99
|
const {table} = this.props
|
|
100
|
-
const {preparedColumns} = table.
|
|
100
|
+
const {preparedColumns} = table.state
|
|
101
101
|
|
|
102
102
|
return (
|
|
103
103
|
<div className="api-maker--table--settings" ref={this.rootRef}>
|
|
@@ -31,7 +31,7 @@ export default class ApiMakerTableSettings {
|
|
|
31
31
|
|
|
32
32
|
columns = () => digg(this, "table", "columnsAsArray")()
|
|
33
33
|
currentUser = () => digg(this, "table", "props", "currentUser")
|
|
34
|
-
identifier = () => digg(this, "table", "
|
|
34
|
+
identifier = () => digg(this, "table", "state", "identifier")
|
|
35
35
|
|
|
36
36
|
preparedColumns = (tableSetting) => {
|
|
37
37
|
const columns = this.table.columnsAsArray()
|
package/src/table/table.jsx
CHANGED
|
@@ -2,7 +2,6 @@ import "./style"
|
|
|
2
2
|
import Card from "../bootstrap/card"
|
|
3
3
|
import classNames from "classnames"
|
|
4
4
|
import Collection from "../collection"
|
|
5
|
-
import CollectionLoader from "../collection-loader"
|
|
6
5
|
import columnVisible from "./column-visible.mjs"
|
|
7
6
|
import debounce from "debounce"
|
|
8
7
|
import {digg, digs} from "diggerize"
|
|
@@ -13,20 +12,21 @@ import ModelRow from "./model-row"
|
|
|
13
12
|
import Paginate from "../bootstrap/paginate"
|
|
14
13
|
import Params from "../params"
|
|
15
14
|
import PropTypes from "prop-types"
|
|
16
|
-
import React from "react"
|
|
15
|
+
import React, {useEffect, useRef} from "react"
|
|
17
16
|
import selectCalculator from "./select-calculator"
|
|
18
17
|
import Select from "../inputs/select"
|
|
19
18
|
import Settings from "./settings"
|
|
20
|
-
import
|
|
19
|
+
import {shapeComponent, ShapeComponent} from "set-state-compare/src/shape-component"
|
|
21
20
|
import SortLink from "../bootstrap/sort-link"
|
|
22
21
|
import TableSettings from "./table-settings"
|
|
23
22
|
import uniqunize from "uniqunize"
|
|
24
|
-
import
|
|
23
|
+
import useBreakpoint from "./use-breakpoint"
|
|
24
|
+
import useCollection from "../use-collection"
|
|
25
25
|
|
|
26
26
|
const paginationOptions = [30, 60, 90, ["All", "all"]]
|
|
27
27
|
const WorkerPluginsCheckAllCheckbox = React.lazy(() => import("./worker-plugins-check-all-checkbox"))
|
|
28
28
|
|
|
29
|
-
class ApiMakerTable extends
|
|
29
|
+
export default shapeComponent(class ApiMakerTable extends ShapeComponent {
|
|
30
30
|
static defaultProps = {
|
|
31
31
|
card: true,
|
|
32
32
|
destroyEnabled: true,
|
|
@@ -77,43 +77,70 @@ class ApiMakerTable extends React.PureComponent {
|
|
|
77
77
|
workplace: PropTypes.bool.isRequired
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
|
|
80
|
+
setup() {
|
|
81
|
+
const {breakpoint} = useBreakpoint()
|
|
81
82
|
|
|
82
|
-
|
|
83
|
-
|
|
83
|
+
this.setInstance({
|
|
84
|
+
breakpoint,
|
|
85
|
+
filterFormRef: useRef()
|
|
86
|
+
})
|
|
84
87
|
|
|
85
|
-
const collectionKey = digg(props.modelClass.modelClassData(), "collectionKey")
|
|
86
|
-
let queryName = props.queryName
|
|
88
|
+
const collectionKey = digg(this.props.modelClass.modelClassData(), "collectionKey")
|
|
89
|
+
let queryName = this.props.queryName
|
|
87
90
|
|
|
88
91
|
if (!queryName) queryName = collectionKey
|
|
89
92
|
|
|
90
93
|
const columnsAsArray = this.columnsAsArray()
|
|
91
94
|
|
|
92
|
-
this.
|
|
95
|
+
this.useStates({
|
|
93
96
|
columns: columnsAsArray,
|
|
94
97
|
currentWorkplace: undefined,
|
|
95
98
|
identifier: this.props.identifier || `${collectionKey}-default`,
|
|
96
|
-
models: undefined,
|
|
97
|
-
overallCount: undefined,
|
|
98
|
-
perPage: 30,
|
|
99
99
|
preload: undefined,
|
|
100
100
|
preparedColumns: undefined,
|
|
101
|
-
query: undefined,
|
|
102
101
|
queryName,
|
|
103
102
|
queryQName: `${queryName}_q`,
|
|
104
103
|
queryPageName: `${queryName}_page`,
|
|
105
104
|
querySName: `${queryName}_s`,
|
|
106
|
-
qParams: undefined,
|
|
107
|
-
result: undefined,
|
|
108
105
|
showFilters: false,
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
106
|
+
showSettings: false,
|
|
107
|
+
tableSetting: undefined,
|
|
108
|
+
tableSettingFullCacheKey: undefined
|
|
112
109
|
})
|
|
113
110
|
|
|
114
|
-
|
|
111
|
+
useEffect(() => {
|
|
112
|
+
this.loadTableSetting()
|
|
113
|
+
|
|
114
|
+
if (this.props.workplace) this.loadCurrentWorkplace()
|
|
115
|
+
}, [])
|
|
116
|
+
|
|
117
|
+
let collectionReady = true
|
|
118
|
+
let select
|
|
119
|
+
|
|
120
|
+
if (!this.state.preparedColumns) {
|
|
121
|
+
collectionReady = false
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (collectionReady) {
|
|
125
|
+
select = selectCalculator({table: this})
|
|
126
|
+
}
|
|
115
127
|
|
|
116
|
-
|
|
128
|
+
this.collection = useCollection({
|
|
129
|
+
abilities: this.abilitiesToLoad(),
|
|
130
|
+
defaultParams: this.props.defaultParams,
|
|
131
|
+
collection: this.props.collection,
|
|
132
|
+
ifCondition: collectionReady,
|
|
133
|
+
modelClass: this.props.modelClass,
|
|
134
|
+
onModelsLoaded: this.props.onModelsLoaded,
|
|
135
|
+
noRecordsAvailableContent: this.props.noRecordsAvailableContent,
|
|
136
|
+
noRecordsFoundContent: this.props.noRecordsFoundContent,
|
|
137
|
+
pagination: true,
|
|
138
|
+
preloads: this.state.preload,
|
|
139
|
+
queryMethod: this.props.queryMethod,
|
|
140
|
+
queryName,
|
|
141
|
+
select,
|
|
142
|
+
selectColumns: this.props.selectColumns
|
|
143
|
+
})
|
|
117
144
|
}
|
|
118
145
|
|
|
119
146
|
async loadCurrentWorkplace() {
|
|
@@ -121,7 +148,7 @@ class ApiMakerTable extends React.PureComponent {
|
|
|
121
148
|
const result = await Workplace.current()
|
|
122
149
|
const currentWorkplace = digg(result, "current", 0)
|
|
123
150
|
|
|
124
|
-
this.
|
|
151
|
+
this.setState({currentWorkplace})
|
|
125
152
|
}
|
|
126
153
|
|
|
127
154
|
async loadTableSetting() {
|
|
@@ -130,7 +157,7 @@ class ApiMakerTable extends React.PureComponent {
|
|
|
130
157
|
const tableSetting = await this.tableSettings.loadExistingOrCreateTableSettings()
|
|
131
158
|
const {columns, preload} = this.tableSettings.preparedColumns(tableSetting)
|
|
132
159
|
|
|
133
|
-
this.
|
|
160
|
+
this.setState({
|
|
134
161
|
preparedColumns: columns,
|
|
135
162
|
preload: this.mergedPreloads(preload),
|
|
136
163
|
tableSetting,
|
|
@@ -138,7 +165,7 @@ class ApiMakerTable extends React.PureComponent {
|
|
|
138
165
|
})
|
|
139
166
|
}
|
|
140
167
|
|
|
141
|
-
updateSettingsFullCacheKey = () => this.
|
|
168
|
+
updateSettingsFullCacheKey = () => this.setState({tableSettingFullCacheKey: this.state.tableSetting.fullCacheKey()})
|
|
142
169
|
|
|
143
170
|
columnsAsArray = () => {
|
|
144
171
|
if (typeof this.props.columns == "function") return this.props.columns()
|
|
@@ -158,30 +185,23 @@ class ApiMakerTable extends React.PureComponent {
|
|
|
158
185
|
|
|
159
186
|
render () {
|
|
160
187
|
const {modelClass, noRecordsAvailableContent, noRecordsFoundContent} = digs(this.props, "modelClass", "noRecordsAvailableContent", "noRecordsFoundContent")
|
|
161
|
-
const {collection, currentUser
|
|
188
|
+
const {collection, currentUser} = this.props
|
|
189
|
+
const {queryName, querySName, showFilters} = digs(this.state, "queryName", "querySName", "showFilters")
|
|
162
190
|
const {
|
|
191
|
+
models,
|
|
163
192
|
overallCount,
|
|
164
|
-
preload,
|
|
165
193
|
qParams,
|
|
166
194
|
query,
|
|
167
|
-
queryName,
|
|
168
|
-
querySName,
|
|
169
195
|
result,
|
|
170
|
-
models,
|
|
171
|
-
showFilters,
|
|
172
196
|
showNoRecordsAvailableContent,
|
|
173
197
|
showNoRecordsFoundContent
|
|
174
198
|
} = digs(
|
|
175
|
-
this.
|
|
199
|
+
this.collection,
|
|
200
|
+
"models",
|
|
176
201
|
"overallCount",
|
|
177
|
-
"preload",
|
|
178
202
|
"qParams",
|
|
179
203
|
"query",
|
|
180
|
-
"queryName",
|
|
181
|
-
"querySName",
|
|
182
204
|
"result",
|
|
183
|
-
"models",
|
|
184
|
-
"showFilters",
|
|
185
205
|
"showNoRecordsAvailableContent",
|
|
186
206
|
"showNoRecordsFoundContent"
|
|
187
207
|
)
|
|
@@ -195,24 +215,6 @@ class ApiMakerTable extends React.PureComponent {
|
|
|
195
215
|
|
|
196
216
|
return (
|
|
197
217
|
<div className={this.className()}>
|
|
198
|
-
{preload !== undefined &&
|
|
199
|
-
<CollectionLoader
|
|
200
|
-
abilities={this.abilitiesToLoad()}
|
|
201
|
-
defaultParams={defaultParams}
|
|
202
|
-
collection={collection}
|
|
203
|
-
component={this}
|
|
204
|
-
modelClass={modelClass}
|
|
205
|
-
onModelsLoaded={onModelsLoaded}
|
|
206
|
-
noRecordsAvailableContent={noRecordsAvailableContent}
|
|
207
|
-
noRecordsFoundContent={noRecordsFoundContent}
|
|
208
|
-
pagination
|
|
209
|
-
preloads={preload}
|
|
210
|
-
queryMethod={queryMethod}
|
|
211
|
-
queryName={queryName}
|
|
212
|
-
select={selectCalculator({table: this})}
|
|
213
|
-
selectColumns={selectColumns}
|
|
214
|
-
/>
|
|
215
|
-
}
|
|
216
218
|
{showNoRecordsAvailableContent &&
|
|
217
219
|
<div className="live-table--no-records-available-content">
|
|
218
220
|
{noRecordsAvailableContent({models, qParams, overallCount})}
|
|
@@ -268,7 +270,6 @@ class ApiMakerTable extends React.PureComponent {
|
|
|
268
270
|
abilities,
|
|
269
271
|
actionsContent,
|
|
270
272
|
appHistory,
|
|
271
|
-
breakPoint,
|
|
272
273
|
card,
|
|
273
274
|
className,
|
|
274
275
|
collection,
|
|
@@ -304,7 +305,7 @@ class ApiMakerTable extends React.PureComponent {
|
|
|
304
305
|
workplace,
|
|
305
306
|
...restProps
|
|
306
307
|
} = this.props
|
|
307
|
-
const {models, qParams, query, result} = digs(this.
|
|
308
|
+
const {models, qParams, query, result} = digs(this.collection, "models", "qParams", "query", "result")
|
|
308
309
|
|
|
309
310
|
let headerContent, PaginationComponent
|
|
310
311
|
|
|
@@ -360,7 +361,7 @@ class ApiMakerTable extends React.PureComponent {
|
|
|
360
361
|
const {filterFormRef, submitFilter, submitFilterDebounce} = digs(this, "filterFormRef", "submitFilter", "submitFilterDebounce")
|
|
361
362
|
const {filterContent, filterSubmitButton} = digs(this.props, "filterContent", "filterSubmitButton")
|
|
362
363
|
const {filterSubmitLabel} = this.props
|
|
363
|
-
const {qParams} = digs(this.
|
|
364
|
+
const {qParams} = digs(this.collection, "qParams")
|
|
364
365
|
|
|
365
366
|
return (
|
|
366
367
|
<form className="live-table--filter-form" onSubmit={this.onFilterFormSubmit} ref={filterFormRef}>
|
|
@@ -386,11 +387,11 @@ class ApiMakerTable extends React.PureComponent {
|
|
|
386
387
|
|
|
387
388
|
onFilterClicked = (e) => {
|
|
388
389
|
e.preventDefault()
|
|
389
|
-
this.
|
|
390
|
+
this.setState({showFilters: !this.state.showFilters})
|
|
390
391
|
}
|
|
391
392
|
|
|
392
393
|
onPerPageChanged = (e) => {
|
|
393
|
-
const {queryName} = digs(this.
|
|
394
|
+
const {queryName} = digs(this.state, "queryName")
|
|
394
395
|
const newPerPageValue = digg(e, "target", "value")
|
|
395
396
|
const perKey = `${queryName}_per`
|
|
396
397
|
const paramsChange = {}
|
|
@@ -402,7 +403,8 @@ class ApiMakerTable extends React.PureComponent {
|
|
|
402
403
|
|
|
403
404
|
tableControls() {
|
|
404
405
|
const {controls} = this.props
|
|
405
|
-
const {
|
|
406
|
+
const {showSettings} = digs(this.state, "showSettings")
|
|
407
|
+
const {models, qParams, query, result} = digs(this.collection, "models", "qParams", "query", "result")
|
|
406
408
|
|
|
407
409
|
return (
|
|
408
410
|
<>
|
|
@@ -423,21 +425,10 @@ class ApiMakerTable extends React.PureComponent {
|
|
|
423
425
|
}
|
|
424
426
|
|
|
425
427
|
tableContent () {
|
|
426
|
-
const {
|
|
427
|
-
const {
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
preparedColumns,
|
|
431
|
-
query,
|
|
432
|
-
tableSettingFullCacheKey
|
|
433
|
-
} = digs(
|
|
434
|
-
this.shape,
|
|
435
|
-
"currentWorkplace",
|
|
436
|
-
"models",
|
|
437
|
-
"preparedColumns",
|
|
438
|
-
"query",
|
|
439
|
-
"tableSettingFullCacheKey"
|
|
440
|
-
)
|
|
428
|
+
const {workplace} = digs(this.props, "workplace")
|
|
429
|
+
const {breakpoint} = digs(this, "breakpoint")
|
|
430
|
+
const {currentWorkplace, preparedColumns, tableSettingFullCacheKey} = digs(this.state, "currentWorkplace", "preparedColumns", "tableSettingFullCacheKey")
|
|
431
|
+
const {models, query} = digs(this.collection, "models", "query")
|
|
441
432
|
const ColumnInHeadComponent = this.columnInHeadComponent()
|
|
442
433
|
const RowComponent = this.rowComponent()
|
|
443
434
|
|
|
@@ -467,7 +458,7 @@ class ApiMakerTable extends React.PureComponent {
|
|
|
467
458
|
<BodyComponent>
|
|
468
459
|
{models.map((model) =>
|
|
469
460
|
<ModelRow
|
|
470
|
-
breakPoint={
|
|
461
|
+
breakPoint={breakpoint}
|
|
471
462
|
cacheKey={model.cacheKey()}
|
|
472
463
|
columnComponent={this.columnComponent()}
|
|
473
464
|
key={model.id()}
|
|
@@ -484,7 +475,7 @@ class ApiMakerTable extends React.PureComponent {
|
|
|
484
475
|
}
|
|
485
476
|
|
|
486
477
|
tableFooter() {
|
|
487
|
-
const {result} = digs(this.
|
|
478
|
+
const {result} = digs(this.collection, "result")
|
|
488
479
|
const currentPage = result.currentPage()
|
|
489
480
|
const totalCount = result.totalCount()
|
|
490
481
|
const perPage = result.perPage()
|
|
@@ -530,7 +521,7 @@ class ApiMakerTable extends React.PureComponent {
|
|
|
530
521
|
}
|
|
531
522
|
|
|
532
523
|
isSmallScreen() {
|
|
533
|
-
if (this.props.
|
|
524
|
+
if (this.props.breakpoint == "xs" || this.props.breakpoint == "sm") return true
|
|
534
525
|
|
|
535
526
|
return false
|
|
536
527
|
}
|
|
@@ -542,7 +533,8 @@ class ApiMakerTable extends React.PureComponent {
|
|
|
542
533
|
|
|
543
534
|
headersContentFromColumns () {
|
|
544
535
|
const {defaultParams} = this.props
|
|
545
|
-
const {preparedColumns
|
|
536
|
+
const {preparedColumns} = digs(this.state, "preparedColumns")
|
|
537
|
+
const {query} = digs(this.collection, "query")
|
|
546
538
|
const ColumnInHeadComponent = this.columnInHeadComponent()
|
|
547
539
|
|
|
548
540
|
return preparedColumns?.map(({column, tableSettingColumn}) => columnVisible(column, tableSettingColumn) &&
|
|
@@ -604,14 +596,14 @@ class ApiMakerTable extends React.PureComponent {
|
|
|
604
596
|
this.submitFilter()
|
|
605
597
|
}
|
|
606
598
|
|
|
607
|
-
onRequestCloseSettings = () => this.
|
|
599
|
+
onRequestCloseSettings = () => this.setState({showSettings: false})
|
|
608
600
|
|
|
609
601
|
onSettingsClicked = (e) => {
|
|
610
602
|
e.preventDefault()
|
|
611
603
|
|
|
612
|
-
const {showSettings} = digs(this.
|
|
604
|
+
const {showSettings} = digs(this.state, "showSettings")
|
|
613
605
|
|
|
614
|
-
this.
|
|
606
|
+
this.setState({showSettings: !showSettings})
|
|
615
607
|
}
|
|
616
608
|
|
|
617
609
|
submitFilter = () => {
|
|
@@ -619,7 +611,7 @@ class ApiMakerTable extends React.PureComponent {
|
|
|
619
611
|
const filterForm = digg(filterFormRef, "current")
|
|
620
612
|
const {appHistory} = this.props
|
|
621
613
|
const qParams = Params.serializeForm(filterForm)
|
|
622
|
-
const {queryQName} = digs(this.
|
|
614
|
+
const {queryQName} = digs(this.state, "queryQName")
|
|
623
615
|
const changeParamsParams = {}
|
|
624
616
|
|
|
625
617
|
changeParamsParams[queryQName] = JSON.stringify(qParams)
|
|
@@ -628,6 +620,4 @@ class ApiMakerTable extends React.PureComponent {
|
|
|
628
620
|
}
|
|
629
621
|
|
|
630
622
|
submitFilterDebounce = debounce(digg(this, "submitFilter"))
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
export default withBreakpoint(ApiMakerTable)
|
|
623
|
+
})
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import {useCallback, useEffect} from "react"
|
|
2
|
+
import apiMakerConfig from "@kaspernj/api-maker/src/config.mjs"
|
|
3
|
+
import useShape from "set-state-compare/src/use-shape.js"
|
|
4
|
+
|
|
5
|
+
const useBreakpoint = () => {
|
|
6
|
+
const s = useShape()
|
|
7
|
+
|
|
8
|
+
const calculateBreakPoint = useCallback(() => {
|
|
9
|
+
const windowWidth = window.innerWidth
|
|
10
|
+
|
|
11
|
+
for (const breakpointData of apiMakerConfig.getBreakPoints()) {
|
|
12
|
+
const breakpoint = breakpointData[0]
|
|
13
|
+
const width = breakpointData[1]
|
|
14
|
+
|
|
15
|
+
if (windowWidth >= width) return breakpoint
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
throw new Error(`Couldn't not find breakpoint from window width: ${windowWidth}`)
|
|
19
|
+
}, [])
|
|
20
|
+
|
|
21
|
+
const onCalled = useCallback(() => {
|
|
22
|
+
const breakpoint = calculateBreakPoint()
|
|
23
|
+
|
|
24
|
+
if (breakpoint != s.s.breakpoint) {
|
|
25
|
+
s.set({breakpoint})
|
|
26
|
+
}
|
|
27
|
+
}, [])
|
|
28
|
+
|
|
29
|
+
s.useStates({
|
|
30
|
+
breakpoint: () => calculateBreakPoint()
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
window.addEventListener("resize", onCalled)
|
|
35
|
+
|
|
36
|
+
return () => {
|
|
37
|
+
window.removeEventListener("resize", onCalled)
|
|
38
|
+
}
|
|
39
|
+
}, [])
|
|
40
|
+
|
|
41
|
+
return {breakpoint: s.s.breakpoint}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export default useBreakpoint
|
|
@@ -1,48 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
import React from "react"
|
|
1
|
+
import useBreakpoint from "./use-breakpoint"
|
|
3
2
|
|
|
4
|
-
export default (WrappedComponent) =>
|
|
5
|
-
|
|
6
|
-
breakPoint: this.calculateBreakPoint()
|
|
7
|
-
}
|
|
3
|
+
export default (WrappedComponent) => (props) => {
|
|
4
|
+
const {breakpoint} = useBreakpoint()
|
|
8
5
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
for (const breakPointData of apiMakerConfig.getBreakPoints()) {
|
|
13
|
-
const breakPoint = breakPointData[0]
|
|
14
|
-
const width = breakPointData[1]
|
|
15
|
-
|
|
16
|
-
if (windowWidth >= width) return breakPoint
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
throw new Error(`Couldn't not find breakPoint from window width: ${windowWidth}`)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
constructor(props) {
|
|
23
|
-
super(props)
|
|
24
|
-
this.onCalled = this.onCalled.bind(this)
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
componentDidMount () {
|
|
28
|
-
window.addEventListener("resize", this.onCalled)
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
componentWillUnmount () {
|
|
32
|
-
window.removeEventListener("resize", this.onCalled)
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
render() {
|
|
36
|
-
return (
|
|
37
|
-
<WrappedComponent breakPoint={this.state.breakPoint} {...this.props} />
|
|
38
|
-
)
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
onCalled = () => {
|
|
42
|
-
const breakPoint = this.calculateBreakPoint()
|
|
43
|
-
|
|
44
|
-
if (breakPoint != this.state.breakPoint) {
|
|
45
|
-
this.setState({breakPoint})
|
|
46
|
-
}
|
|
47
|
-
}
|
|
6
|
+
return (
|
|
7
|
+
<WrappedComponent breakPoint={breakpoint} {...props} />
|
|
8
|
+
)
|
|
48
9
|
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import classNames from "classnames"
|
|
1
2
|
import Collection from "../collection.mjs"
|
|
2
3
|
import EventConnection from "../event-connection"
|
|
4
|
+
import PropTypes from "prop-types"
|
|
3
5
|
import PropTypesExact from "prop-types-exact"
|
|
6
|
+
import React from "react"
|
|
4
7
|
import {simpleObjectDifferent} from "set-state-compare/src/diff-utils"
|
|
5
8
|
import {useEffect, useRef} from "react"
|
|
6
9
|
|
|
@@ -17,7 +20,7 @@ const Checkbox = (props) => {
|
|
|
17
20
|
)
|
|
18
21
|
}
|
|
19
22
|
|
|
20
|
-
export default class ApiMakerTableWorkerPluginsCheckAllCheckbox extends
|
|
23
|
+
export default class ApiMakerTableWorkerPluginsCheckAllCheckbox extends React.PureComponent {
|
|
21
24
|
static propTypes = PropTypesExact({
|
|
22
25
|
currentWorkplace: PropTypes.object,
|
|
23
26
|
query: PropTypes.instanceOf(Collection)
|
|
@@ -1,21 +1,29 @@
|
|
|
1
|
+
import classNames from "classnames"
|
|
2
|
+
import {digg} from "diggerize"
|
|
1
3
|
import EventConnection from "../event-connection"
|
|
2
4
|
import modelClassRequire from "../model-class-require.mjs"
|
|
5
|
+
import PropTypes from "prop-types"
|
|
3
6
|
import PropTypesExact from "prop-types-exact"
|
|
7
|
+
import React, {useEffect} from "react"
|
|
8
|
+
import {shapeComponent, ShapeComponent} from "set-state-compare/src/shape-component"
|
|
4
9
|
|
|
5
10
|
const Workplace = modelClassRequire("Workplace")
|
|
6
11
|
|
|
7
|
-
export default class ApiMakerTableWorkerPluginsCheckbox extends
|
|
12
|
+
export default shapeComponent(class ApiMakerTableWorkerPluginsCheckbox extends ShapeComponent {
|
|
8
13
|
static propTypes = PropTypesExact({
|
|
9
14
|
currentWorkplace: PropTypes.object,
|
|
10
15
|
model: PropTypes.object.isRequired
|
|
11
16
|
})
|
|
12
17
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
18
|
+
setup() {
|
|
19
|
+
this.useStates({
|
|
20
|
+
checked: false,
|
|
21
|
+
linkLoaded: false
|
|
22
|
+
})
|
|
16
23
|
|
|
17
|
-
|
|
18
|
-
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
this.loadCurrentLink()
|
|
26
|
+
}, [])
|
|
19
27
|
}
|
|
20
28
|
|
|
21
29
|
async loadCurrentLink() {
|
|
@@ -23,7 +31,7 @@ export default class ApiMakerTableWorkerPluginsCheckbox extends BaseComponent {
|
|
|
23
31
|
const response = await Workplace.linkFor({model_class: model.modelClassData().name, model_id: model.id()})
|
|
24
32
|
const link = digg(response, "link")
|
|
25
33
|
|
|
26
|
-
this.
|
|
34
|
+
this.setState({
|
|
27
35
|
checked: Boolean(link),
|
|
28
36
|
linkLoaded: true
|
|
29
37
|
})
|
|
@@ -31,7 +39,7 @@ export default class ApiMakerTableWorkerPluginsCheckbox extends BaseComponent {
|
|
|
31
39
|
|
|
32
40
|
render() {
|
|
33
41
|
const {className, currentWorkplace, model} = this.props
|
|
34
|
-
const {checked, linkLoaded} = this.
|
|
42
|
+
const {checked, linkLoaded} = this.state
|
|
35
43
|
|
|
36
44
|
if (!linkLoaded) {
|
|
37
45
|
return null
|
|
@@ -81,7 +89,7 @@ export default class ApiMakerTableWorkerPluginsCheckbox extends BaseComponent {
|
|
|
81
89
|
const modelClassName = model.modelClassData().name
|
|
82
90
|
|
|
83
91
|
if (args.created[modelClassName] && args.created[modelClassName].includes(id)) {
|
|
84
|
-
this.
|
|
92
|
+
this.setState({checked: true})
|
|
85
93
|
}
|
|
86
94
|
}
|
|
87
95
|
|
|
@@ -91,7 +99,7 @@ export default class ApiMakerTableWorkerPluginsCheckbox extends BaseComponent {
|
|
|
91
99
|
const modelClassName = model.modelClassData().name
|
|
92
100
|
|
|
93
101
|
if (args.destroyed[modelClassName] && args.destroyed[modelClassName].includes(id)) {
|
|
94
|
-
this.
|
|
102
|
+
this.setState({checked: false})
|
|
95
103
|
}
|
|
96
104
|
}
|
|
97
|
-
}
|
|
105
|
+
})
|
package/src/use-collection.mjs
CHANGED
|
@@ -12,6 +12,7 @@ const useCollection = (
|
|
|
12
12
|
collection,
|
|
13
13
|
defaultParams,
|
|
14
14
|
groupBy = ["id"],
|
|
15
|
+
ifCondition,
|
|
15
16
|
limit,
|
|
16
17
|
modelClass,
|
|
17
18
|
noRecordsAvailableContent = undefined,
|
|
@@ -37,6 +38,7 @@ const useCollection = (
|
|
|
37
38
|
collection,
|
|
38
39
|
defaultParams,
|
|
39
40
|
groupBy,
|
|
41
|
+
ifCondition,
|
|
40
42
|
limit,
|
|
41
43
|
modelClass,
|
|
42
44
|
noRecordsAvailableContent,
|
|
@@ -240,10 +242,13 @@ const useCollection = (
|
|
|
240
242
|
|
|
241
243
|
useEffect(
|
|
242
244
|
() => {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
+
if (!("ifCondition" in s.props) || s.props.ifCondition) {
|
|
246
|
+
loadQParams()
|
|
247
|
+
loadModels()
|
|
248
|
+
}
|
|
245
249
|
},
|
|
246
250
|
[
|
|
251
|
+
s.props.ifCondition,
|
|
247
252
|
s.m.queryParams[s.s.queryQName],
|
|
248
253
|
s.m.queryParams[s.s.queryPageName],
|
|
249
254
|
s.m.queryParams[s.s.queryPerKey],
|
|
@@ -256,8 +261,12 @@ const useCollection = (
|
|
|
256
261
|
if (s.p.noRecordsAvailableContent) loadOverallCount()
|
|
257
262
|
}, [])
|
|
258
263
|
|
|
264
|
+
const onCreated = useCallback(() => {
|
|
265
|
+
loadModels()
|
|
266
|
+
}, [])
|
|
267
|
+
|
|
259
268
|
useEffect(() => {
|
|
260
|
-
const connectCreated = ModelEvents.connectCreated(s.p.modelClass,
|
|
269
|
+
const connectCreated = ModelEvents.connectCreated(s.p.modelClass, onCreated)
|
|
261
270
|
|
|
262
271
|
return () => {
|
|
263
272
|
connectCreated.unsubscribe()
|