@kaspernj/api-maker 1.0.373 → 1.0.374
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/cable-connection-pool.mjs +3 -7
- package/src/commands-pool.mjs +5 -31
- package/src/run-last.mjs +39 -0
- package/src/table/filters/attribute-element.jsx +42 -0
- package/src/table/filters/filter-form.jsx +36 -131
- package/src/table/filters/filter.jsx +55 -0
- package/src/table/filters/index.jsx +2 -50
- package/src/table/filters/reflection-element.jsx +35 -0
- package/src/table/filters/scope-element.jsx +39 -0
- package/src/table/table.jsx +8 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kaspernj/api-maker",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.374",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "",
|
|
6
6
|
"main": "index.js",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"on-location-changed": ">= 1.0.10",
|
|
36
36
|
"qs": ">= 6.9.3",
|
|
37
37
|
"replaceall": ">= 0.1.6",
|
|
38
|
-
"set-state-compare": "^1.0.
|
|
38
|
+
"set-state-compare": "^1.0.45",
|
|
39
39
|
"spark-md5": "^3.0.2",
|
|
40
40
|
"stacktrace-parser": "^0.1.10",
|
|
41
41
|
"strftime": ">= 0.10.0",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import CableSubscriptionPool from "./cable-subscription-pool.mjs"
|
|
2
2
|
import CableSubscription from "./cable-subscription.mjs"
|
|
3
3
|
import {dig} from "diggerize"
|
|
4
|
+
import RunLast from "./run-last.mjs"
|
|
4
5
|
|
|
5
6
|
const shared = {}
|
|
6
7
|
|
|
@@ -96,7 +97,7 @@ export default class ApiMakerCableConnectionPool {
|
|
|
96
97
|
currentSubscription[value].push(subscription)
|
|
97
98
|
}
|
|
98
99
|
|
|
99
|
-
this.
|
|
100
|
+
this.scheduleConnectUpcomingRunLast.queue()
|
|
100
101
|
|
|
101
102
|
return subscription
|
|
102
103
|
}
|
|
@@ -122,10 +123,5 @@ export default class ApiMakerCableConnectionPool {
|
|
|
122
123
|
this.cableSubscriptionPools.push(cableSubscriptionPool)
|
|
123
124
|
}
|
|
124
125
|
|
|
125
|
-
|
|
126
|
-
if (this.scheduleConnectUpcomingTimeout)
|
|
127
|
-
clearTimeout(this.scheduleConnectUpcomingTimeout)
|
|
128
|
-
|
|
129
|
-
this.scheduleConnectUpcomingTimeout = setTimeout(this.connectUpcoming, 0)
|
|
130
|
-
}
|
|
126
|
+
scheduleConnectUpcomingRunLast = new RunLast(this.connectUpcoming)
|
|
131
127
|
}
|
package/src/commands-pool.mjs
CHANGED
|
@@ -6,6 +6,7 @@ import Deserializer from "./deserializer.mjs"
|
|
|
6
6
|
import {dig, digg} from "diggerize"
|
|
7
7
|
import events from "./events.mjs"
|
|
8
8
|
import FormDataObjectizer from "form-data-objectizer"
|
|
9
|
+
import RunLast from "./run-last.mjs"
|
|
9
10
|
import Serializer from "./serializer.mjs"
|
|
10
11
|
import SessionStatusUpdater from "./session-status-updater.mjs"
|
|
11
12
|
import ValidationError from "./validation-error.mjs"
|
|
@@ -26,9 +27,9 @@ export default class ApiMakerCommandsPool {
|
|
|
26
27
|
const promiseResult = pool.addCommand(data)
|
|
27
28
|
|
|
28
29
|
if (args.instant) {
|
|
29
|
-
pool.
|
|
30
|
+
pool.flushRunLast.run()
|
|
30
31
|
} else {
|
|
31
|
-
pool.
|
|
32
|
+
pool.flushRunLast.queue()
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
return promiseResult
|
|
@@ -115,13 +116,11 @@ export default class ApiMakerCommandsPool {
|
|
|
115
116
|
throw new Error("Couldnt successfully execute request")
|
|
116
117
|
}
|
|
117
118
|
|
|
118
|
-
async
|
|
119
|
+
flush = async () => {
|
|
119
120
|
if (this.commandsCount() == 0) {
|
|
120
121
|
return
|
|
121
122
|
}
|
|
122
123
|
|
|
123
|
-
this.clearTimeout()
|
|
124
|
-
|
|
125
124
|
const currentPool = this.pool
|
|
126
125
|
const currentPoolData = this.poolData
|
|
127
126
|
|
|
@@ -197,12 +196,6 @@ export default class ApiMakerCommandsPool {
|
|
|
197
196
|
commandData.reject(error)
|
|
198
197
|
}
|
|
199
198
|
|
|
200
|
-
clearTimeout() {
|
|
201
|
-
if (this.flushTimeout) {
|
|
202
|
-
clearTimeout(this.flushTimeout)
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
199
|
isActive() {
|
|
207
200
|
if (this.commandsCount() > 0) {
|
|
208
201
|
return true
|
|
@@ -215,24 +208,5 @@ export default class ApiMakerCommandsPool {
|
|
|
215
208
|
return false
|
|
216
209
|
}
|
|
217
210
|
|
|
218
|
-
|
|
219
|
-
// If only waiting a single time, then other event-queue-jobs might be before us and queue other jobs that might queue calls to the backend
|
|
220
|
-
setFlushTimeout() {
|
|
221
|
-
this.flushTriggerCount = 0
|
|
222
|
-
this.clearTimeout()
|
|
223
|
-
this.flushTrigger()
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
flushTrigger = () => {
|
|
227
|
-
if (this.flushTriggerCount >= 10) {
|
|
228
|
-
this.flush()
|
|
229
|
-
} else {
|
|
230
|
-
this.flushTriggerCount++
|
|
231
|
-
this.flushTriggerQueue()
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
flushTriggerQueue() {
|
|
236
|
-
this.flushTimeout = setTimeout(this.flushTrigger, 0)
|
|
237
|
-
}
|
|
211
|
+
flushRunLast = new RunLast(this.flush)
|
|
238
212
|
}
|
package/src/run-last.mjs
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export default class RunLast {
|
|
2
|
+
constructor(callback) {
|
|
3
|
+
if (!callback) throw new Error("Empty callback given")
|
|
4
|
+
|
|
5
|
+
this.callback = callback
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// Try to batch calls to backend while waiting for the event-queue-call to clear any other jobs before the request and reset on every flush call
|
|
9
|
+
// If only waiting a single time, then other event-queue-jobs might be before us and queue other jobs that might queue calls to the backend
|
|
10
|
+
queue() {
|
|
11
|
+
this.flushTriggerCount = 0
|
|
12
|
+
this.clearTimeout()
|
|
13
|
+
this.flushTrigger()
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
flushTrigger = () => {
|
|
17
|
+
if (this.flushTriggerCount >= 10) {
|
|
18
|
+
this.run()
|
|
19
|
+
} else {
|
|
20
|
+
this.flushTriggerCount++
|
|
21
|
+
this.flushTriggerQueue()
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
flushTriggerQueue() {
|
|
26
|
+
this.flushTimeout = setTimeout(this.flushTrigger, 0)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
clearTimeout() {
|
|
30
|
+
if (this.flushTimeout) {
|
|
31
|
+
clearTimeout(this.flushTimeout)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
run() {
|
|
36
|
+
clearTimeout(this.flushTimeout)
|
|
37
|
+
this.callback()
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import Attribute from "../../base-model/attribute"
|
|
2
|
+
import {digg, digs} from "diggerize"
|
|
3
|
+
import * as inflection from "inflection"
|
|
4
|
+
import PropTypes from "prop-types"
|
|
5
|
+
import PropTypesExact from "prop-types-exact"
|
|
6
|
+
import {memo} from "react"
|
|
7
|
+
import {shapeComponent, ShapeComponent} from "set-state-compare/src/shape-component"
|
|
8
|
+
|
|
9
|
+
export default memo(shapeComponent(class AttributeElement extends ShapeComponent {
|
|
10
|
+
static propTypes = PropTypesExact({
|
|
11
|
+
active: PropTypes.bool.isRequired,
|
|
12
|
+
attribute: PropTypes.instanceOf(Attribute).isRequired,
|
|
13
|
+
currentModelClass: PropTypes.func.isRequired,
|
|
14
|
+
fikter: PropTypes.object,
|
|
15
|
+
onClick: PropTypes.func.isRequired
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
render() {
|
|
19
|
+
const {active, attribute, currentModelClass} = digs(this.props, "active", "attribute", "currentModelClass")
|
|
20
|
+
const style = {}
|
|
21
|
+
|
|
22
|
+
if (active) style.fontWeight = "bold"
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<div
|
|
26
|
+
className="attribute-element"
|
|
27
|
+
data-attribute-name={attribute.name()}
|
|
28
|
+
data-model-class={currentModelClass.modelClassData().name}
|
|
29
|
+
onClick={digg(this, "onAttributeClicked")}
|
|
30
|
+
style={style}
|
|
31
|
+
>
|
|
32
|
+
{currentModelClass.humanAttributeName(inflection.camelize(attribute.name(), true))}
|
|
33
|
+
</div>
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
onAttributeClicked = (e) => {
|
|
38
|
+
e.preventDefault()
|
|
39
|
+
|
|
40
|
+
this.props.onClick({attribute: digg(this, "props", "attribute")})
|
|
41
|
+
}
|
|
42
|
+
}))
|
|
@@ -1,116 +1,17 @@
|
|
|
1
|
-
import
|
|
1
|
+
import AttributeElement from "./attribute-element"
|
|
2
2
|
import {digg, digs} from "diggerize"
|
|
3
3
|
import * as inflection from "inflection"
|
|
4
4
|
import Input from "../../inputs/input"
|
|
5
5
|
import PropTypes from "prop-types"
|
|
6
6
|
import PropTypesExact from "prop-types-exact"
|
|
7
|
-
import
|
|
8
|
-
import
|
|
7
|
+
import {memo, useMemo, useRef} from "react"
|
|
8
|
+
import ReflectionElement from "./reflection-element"
|
|
9
|
+
import ScopeElement from "./scope-element"
|
|
9
10
|
import Select from "../../inputs/select"
|
|
10
11
|
import Services from "../../services.mjs"
|
|
11
|
-
import
|
|
12
|
+
import {shapeComponent, ShapeComponent} from "set-state-compare/src/shape-component"
|
|
12
13
|
|
|
13
|
-
class
|
|
14
|
-
static propTypes = PropTypesExact({
|
|
15
|
-
active: PropTypes.bool.isRequired,
|
|
16
|
-
attribute: PropTypes.instanceOf(Attribute).isRequired,
|
|
17
|
-
currentModelClass: PropTypes.func.isRequired,
|
|
18
|
-
fikter: PropTypes.object,
|
|
19
|
-
onClick: PropTypes.func.isRequired
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
render() {
|
|
23
|
-
const {active, attribute, currentModelClass} = digs(this.props, "active", "attribute", "currentModelClass")
|
|
24
|
-
const style = {}
|
|
25
|
-
|
|
26
|
-
if (active) style.fontWeight = "bold"
|
|
27
|
-
|
|
28
|
-
return (
|
|
29
|
-
<div
|
|
30
|
-
className="attribute-element"
|
|
31
|
-
data-attribute-name={attribute.name()}
|
|
32
|
-
data-model-class={currentModelClass.modelClassData().name}
|
|
33
|
-
onClick={digg(this, "onAttributeClicked")}
|
|
34
|
-
style={style}
|
|
35
|
-
>
|
|
36
|
-
{currentModelClass.humanAttributeName(inflection.camelize(attribute.name(), true))}
|
|
37
|
-
</div>
|
|
38
|
-
)
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
onAttributeClicked = (e) => {
|
|
42
|
-
e.preventDefault()
|
|
43
|
-
|
|
44
|
-
this.props.onClick({attribute: digg(this, "props", "attribute")})
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
class ReflectionElement extends React.PureComponent {
|
|
49
|
-
static propTypes = PropTypesExact({
|
|
50
|
-
currentModelClass: PropTypes.func.isRequired,
|
|
51
|
-
onClick: PropTypes.func.isRequired,
|
|
52
|
-
reflection: PropTypes.instanceOf(Reflection).isRequired
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
render() {
|
|
56
|
-
const {currentModelClass, reflection} = digs(this.props, "currentModelClass", "reflection")
|
|
57
|
-
|
|
58
|
-
return (
|
|
59
|
-
<div
|
|
60
|
-
className="reflection-element"
|
|
61
|
-
data-model-class={currentModelClass.modelClassData().name}
|
|
62
|
-
data-reflection-name={reflection.name()}
|
|
63
|
-
onClick={digg(this, "onReflectionClicked")}
|
|
64
|
-
>
|
|
65
|
-
{currentModelClass.humanAttributeName(reflection.name())}
|
|
66
|
-
</div>
|
|
67
|
-
)
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
onReflectionClicked = (e) => {
|
|
71
|
-
e.preventDefault()
|
|
72
|
-
|
|
73
|
-
this.props.onClick({reflection: digg(this, "props", "reflection")})
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
class ScopeElement extends React.PureComponent {
|
|
78
|
-
static defaultProps = {
|
|
79
|
-
active: false
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
static propTypes = {
|
|
83
|
-
active: PropTypes.bool.isRequired,
|
|
84
|
-
scope: PropTypes.object.isRequired
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
render() {
|
|
88
|
-
const {active, scope} = this.props
|
|
89
|
-
const style = {}
|
|
90
|
-
|
|
91
|
-
if (active) style.fontWeight = "bold"
|
|
92
|
-
|
|
93
|
-
return (
|
|
94
|
-
<div
|
|
95
|
-
className="scope-element"
|
|
96
|
-
key={scope.name()}
|
|
97
|
-
onClick={digg(this, "onScopeClicked")}
|
|
98
|
-
style={style}
|
|
99
|
-
>
|
|
100
|
-
{scope.name()}
|
|
101
|
-
</div>
|
|
102
|
-
)
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
onScopeClicked = (e) => {
|
|
106
|
-
e.preventDefault()
|
|
107
|
-
|
|
108
|
-
this.props.onScopeClicked({scope: this.props.scope})
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
export default class ApiMakerTableFiltersFilterForm extends React.PureComponent {
|
|
14
|
+
export default memo(shapeComponent(class ApiMakerTableFiltersFilterForm extends ShapeComponent {
|
|
114
15
|
static propTypes = PropTypesExact({
|
|
115
16
|
filter: PropTypes.object,
|
|
116
17
|
modelClass: PropTypes.func.isRequired,
|
|
@@ -118,18 +19,22 @@ export default class ApiMakerTableFiltersFilterForm extends React.PureComponent
|
|
|
118
19
|
querySearchName: PropTypes.string.isRequired
|
|
119
20
|
})
|
|
120
21
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
22
|
+
setup() {
|
|
23
|
+
this.useStates({
|
|
24
|
+
attribute: () => this.currentModelClassFromPath(this.props.filter.p || [])
|
|
25
|
+
.ransackableAttributes()
|
|
26
|
+
.find((attribute) => attribute.name() == this.props.filter.a),
|
|
27
|
+
path: this.props.filter.p || [],
|
|
28
|
+
predicate: undefined,
|
|
29
|
+
predicates: undefined,
|
|
30
|
+
scope: this.props.filter.sc,
|
|
31
|
+
value: this.props.filter.v
|
|
32
|
+
})
|
|
33
|
+
this.valueInputRef = useRef()
|
|
130
34
|
|
|
131
|
-
|
|
132
|
-
|
|
35
|
+
useMemo(() => {
|
|
36
|
+
this.loadRansackPredicates()
|
|
37
|
+
}, [])
|
|
133
38
|
}
|
|
134
39
|
|
|
135
40
|
async loadRansackPredicates() {
|
|
@@ -141,7 +46,7 @@ export default class ApiMakerTableFiltersFilterForm extends React.PureComponent
|
|
|
141
46
|
currentPredicate = predicates.find((predicate) => predicate.name == this.props.filter.pre)
|
|
142
47
|
}
|
|
143
48
|
|
|
144
|
-
this.
|
|
49
|
+
this.setState({
|
|
145
50
|
predicate: currentPredicate,
|
|
146
51
|
predicates
|
|
147
52
|
})
|
|
@@ -150,7 +55,7 @@ export default class ApiMakerTableFiltersFilterForm extends React.PureComponent
|
|
|
150
55
|
render() {
|
|
151
56
|
const {valueInputRef} = digs(this, "valueInputRef")
|
|
152
57
|
const currentModelClass = this.currentModelClass()
|
|
153
|
-
const {attribute, predicate, predicates, scope, value} = digs(this.
|
|
58
|
+
const {attribute, predicate, predicates, scope, value} = digs(this.state, "attribute", "predicate", "scope", "predicates", "value")
|
|
154
59
|
let submitEnabled = false
|
|
155
60
|
|
|
156
61
|
if (attribute && predicate) {
|
|
@@ -188,7 +93,7 @@ export default class ApiMakerTableFiltersFilterForm extends React.PureComponent
|
|
|
188
93
|
<div>
|
|
189
94
|
{this.sortedByName(currentModelClass.ransackableAttributes(), currentModelClass).map((attribute) =>
|
|
190
95
|
<AttributeElement
|
|
191
|
-
active={attribute.name() == this.
|
|
96
|
+
active={attribute.name() == this.state.attribute?.name()}
|
|
192
97
|
attribute={attribute}
|
|
193
98
|
currentModelClass={currentModelClass}
|
|
194
99
|
key={attribute.name()}
|
|
@@ -197,7 +102,7 @@ export default class ApiMakerTableFiltersFilterForm extends React.PureComponent
|
|
|
197
102
|
)}
|
|
198
103
|
{currentModelClass.ransackableScopes().map((scope) =>
|
|
199
104
|
<ScopeElement
|
|
200
|
-
active={scope.name() == this.
|
|
105
|
+
active={scope.name() == this.state.scope?.name()}
|
|
201
106
|
key={scope.name()}
|
|
202
107
|
scope={scope}
|
|
203
108
|
onScopeClicked={digg(this, "onScopeClicked")}
|
|
@@ -205,7 +110,7 @@ export default class ApiMakerTableFiltersFilterForm extends React.PureComponent
|
|
|
205
110
|
)}
|
|
206
111
|
</div>
|
|
207
112
|
<div>
|
|
208
|
-
{predicates && !this.
|
|
113
|
+
{predicates && !this.state.scope &&
|
|
209
114
|
<Select
|
|
210
115
|
className="predicate-select"
|
|
211
116
|
defaultValue={predicate?.name}
|
|
@@ -232,7 +137,7 @@ export default class ApiMakerTableFiltersFilterForm extends React.PureComponent
|
|
|
232
137
|
}
|
|
233
138
|
|
|
234
139
|
currentModelClass() {
|
|
235
|
-
const {path} = digs(this.
|
|
140
|
+
const {path} = digs(this.state, "path")
|
|
236
141
|
|
|
237
142
|
return this.currentModelClassFromPath(path)
|
|
238
143
|
}
|
|
@@ -259,7 +164,7 @@ export default class ApiMakerTableFiltersFilterForm extends React.PureComponent
|
|
|
259
164
|
|
|
260
165
|
currentPathParts() {
|
|
261
166
|
const {modelClass} = digs(this.props, "modelClass")
|
|
262
|
-
const {path} = digs(this.
|
|
167
|
+
const {path} = digs(this.state, "path")
|
|
263
168
|
const result = []
|
|
264
169
|
let currentModelClass = modelClass
|
|
265
170
|
|
|
@@ -284,7 +189,7 @@ export default class ApiMakerTableFiltersFilterForm extends React.PureComponent
|
|
|
284
189
|
}
|
|
285
190
|
|
|
286
191
|
onAttributeClicked = ({attribute}) => {
|
|
287
|
-
this.
|
|
192
|
+
this.setState({
|
|
288
193
|
attribute,
|
|
289
194
|
predicate: undefined,
|
|
290
195
|
scope: undefined
|
|
@@ -293,15 +198,15 @@ export default class ApiMakerTableFiltersFilterForm extends React.PureComponent
|
|
|
293
198
|
|
|
294
199
|
onPredicateChanged = (e) => {
|
|
295
200
|
const chosenPredicateName = digg(e, "target", "value")
|
|
296
|
-
const predicate = this.
|
|
201
|
+
const predicate = this.state.predicates.find((predicate) => predicate.name == chosenPredicateName)
|
|
297
202
|
|
|
298
|
-
this.
|
|
203
|
+
this.setState({predicate})
|
|
299
204
|
}
|
|
300
205
|
|
|
301
206
|
onReflectionClicked = ({reflection}) => {
|
|
302
|
-
const newPath = this.
|
|
207
|
+
const newPath = this.state.path.concat([inflection.underscore(reflection.name())])
|
|
303
208
|
|
|
304
|
-
this.
|
|
209
|
+
this.setState({
|
|
305
210
|
attribute: undefined,
|
|
306
211
|
path: newPath,
|
|
307
212
|
predicate: undefined
|
|
@@ -311,7 +216,7 @@ export default class ApiMakerTableFiltersFilterForm extends React.PureComponent
|
|
|
311
216
|
}
|
|
312
217
|
|
|
313
218
|
onScopeClicked = ({scope}) => {
|
|
314
|
-
this.
|
|
219
|
+
this.setState({
|
|
315
220
|
attribute: undefined,
|
|
316
221
|
scope
|
|
317
222
|
})
|
|
@@ -321,7 +226,7 @@ export default class ApiMakerTableFiltersFilterForm extends React.PureComponent
|
|
|
321
226
|
e.preventDefault()
|
|
322
227
|
|
|
323
228
|
const {filter, querySearchName} = digs(this.props, "filter", "querySearchName")
|
|
324
|
-
const {attribute, path, predicate, scope} = digs(this.
|
|
229
|
+
const {attribute, path, predicate, scope} = digs(this.state, "attribute", "path", "predicate", "scope")
|
|
325
230
|
const {filterIndex} = digs(filter, "filterIndex")
|
|
326
231
|
const searchParams = Params.parse()[querySearchName] || {}
|
|
327
232
|
const value = digg(this, "valueInputRef", "current", "value")
|
|
@@ -367,4 +272,4 @@ export default class ApiMakerTableFiltersFilterForm extends React.PureComponent
|
|
|
367
272
|
currentModelClass.humanAttributeName(a.name()).toLowerCase().localeCompare(currentModelClass.humanAttributeName(b.name()).toLowerCase())
|
|
368
273
|
)
|
|
369
274
|
}
|
|
370
|
-
}
|
|
275
|
+
}))
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import {digg, digs} from "diggerize"
|
|
2
|
+
import PropTypes from "prop-types"
|
|
3
|
+
import PropTypesExact from "prop-types-exact"
|
|
4
|
+
import {memo} from "react"
|
|
5
|
+
import {shapeComponent, ShapeComponent} from "set-state-compare/src/shape-component"
|
|
6
|
+
|
|
7
|
+
export default memo(shapeComponent(class ApiMakerTableFilter extends ShapeComponent {
|
|
8
|
+
static propTypes = PropTypesExact({
|
|
9
|
+
a: PropTypes.string,
|
|
10
|
+
filterIndex: PropTypes.number.isRequired,
|
|
11
|
+
onClick: PropTypes.func.isRequired,
|
|
12
|
+
onRemoveClicked: PropTypes.func.isRequired,
|
|
13
|
+
p: PropTypes.array.isRequired,
|
|
14
|
+
pre: PropTypes.string,
|
|
15
|
+
sc: PropTypes.string,
|
|
16
|
+
v: PropTypes.string.isRequired
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
render() {
|
|
20
|
+
const {p, v} = digs(this.props, "p", "v")
|
|
21
|
+
const {a, pre, sc} = this.props
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<div style={{display: "inline-block", backgroundColor: "grey", padding: "10px 6px"}}>
|
|
25
|
+
<span className="filter-label" onClick={digg(this, "onFilterClicked")} style={{cursor: "pointer"}}>
|
|
26
|
+
{p.length > 0 &&
|
|
27
|
+
`${p.join(".")}.`
|
|
28
|
+
}
|
|
29
|
+
{a} {sc} {pre} {v}
|
|
30
|
+
</span>
|
|
31
|
+
<span>
|
|
32
|
+
<a className="remove-filter-button" href="#" onClick={digg(this, "onRemoveFilterClicked")}>
|
|
33
|
+
<i className="fa fa-remove la la-remove" />
|
|
34
|
+
</a>
|
|
35
|
+
</span>
|
|
36
|
+
</div>
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
onFilterClicked = (e) => {
|
|
41
|
+
e.preventDefault()
|
|
42
|
+
|
|
43
|
+
const {a, filterIndex, p, pre, v} = digs(this.props, "a", "filterIndex", "p", "pre", "v")
|
|
44
|
+
|
|
45
|
+
this.props.onClick({a, filterIndex, p, pre, v})
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
onRemoveFilterClicked = (e) => {
|
|
49
|
+
e.preventDefault()
|
|
50
|
+
|
|
51
|
+
const {filterIndex} = digs(this.props, "filterIndex")
|
|
52
|
+
|
|
53
|
+
this.props.onRemoveClicked({filterIndex})
|
|
54
|
+
}
|
|
55
|
+
}))
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {digg, digs} from "diggerize"
|
|
2
|
+
import Filter from "./filter"
|
|
2
3
|
import FilterForm from "./filter-form"
|
|
3
4
|
import LoadSearchModal from "./load-search-modal"
|
|
4
5
|
import SaveSearchModal from "./save-search-modal"
|
|
@@ -8,55 +9,6 @@ import {shapeComponent, ShapeComponent} from "set-state-compare/src/shape-compon
|
|
|
8
9
|
import useI18n from "i18n-on-steroids/src/use-i18n.mjs"
|
|
9
10
|
import useQueryParams from "on-location-changed/src/use-query-params"
|
|
10
11
|
|
|
11
|
-
const ApiMakerTableFilter = memo(shapeComponent(class ApiMakerTableFilter extends ShapeComponent {
|
|
12
|
-
static propTypes = {
|
|
13
|
-
a: PropTypes.string.isRequired,
|
|
14
|
-
filterIndex: PropTypes.number.isRequired,
|
|
15
|
-
onClick: PropTypes.func.isRequired,
|
|
16
|
-
onRemoveClicked: PropTypes.func.isRequired,
|
|
17
|
-
p: PropTypes.array.isRequired,
|
|
18
|
-
pre: PropTypes.string.isRequired,
|
|
19
|
-
v: PropTypes.string.isRequired
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
render() {
|
|
23
|
-
const {p, v} = digs(this.props, "p", "v")
|
|
24
|
-
const {a, pre, sc} = this.props
|
|
25
|
-
|
|
26
|
-
return (
|
|
27
|
-
<div style={{display: "inline-block", backgroundColor: "grey", padding: "10px 6px"}}>
|
|
28
|
-
<span className="filter-label" onClick={digg(this, "onFilterClicked")} style={{cursor: "pointer"}}>
|
|
29
|
-
{p.length > 0 &&
|
|
30
|
-
`${p.join(".")}.`
|
|
31
|
-
}
|
|
32
|
-
{a} {sc} {pre} {v}
|
|
33
|
-
</span>
|
|
34
|
-
<span>
|
|
35
|
-
<a className="remove-filter-button" href="#" onClick={digg(this, "onRemoveFilterClicked")}>
|
|
36
|
-
<i className="fa fa-remove la la-remove" />
|
|
37
|
-
</a>
|
|
38
|
-
</span>
|
|
39
|
-
</div>
|
|
40
|
-
)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
onFilterClicked = (e) => {
|
|
44
|
-
e.preventDefault()
|
|
45
|
-
|
|
46
|
-
const {a, filterIndex, p, pre, v} = digs(this.props, "a", "filterIndex", "p", "pre", "v")
|
|
47
|
-
|
|
48
|
-
this.props.onClick({a, filterIndex, p, pre, v})
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
onRemoveFilterClicked = (e) => {
|
|
52
|
-
e.preventDefault()
|
|
53
|
-
|
|
54
|
-
const {filterIndex} = digs(this.props, "filterIndex")
|
|
55
|
-
|
|
56
|
-
this.props.onRemoveClicked({filterIndex})
|
|
57
|
-
}
|
|
58
|
-
}))
|
|
59
|
-
|
|
60
12
|
export default memo(shapeComponent(class ApiMakerTableFilters extends ShapeComponent {
|
|
61
13
|
static propTypes = {
|
|
62
14
|
currentUser: PropTypes.object,
|
|
@@ -110,7 +62,7 @@ export default memo(shapeComponent(class ApiMakerTableFilters extends ShapeCompo
|
|
|
110
62
|
/>
|
|
111
63
|
}
|
|
112
64
|
{currentFilters?.map((filterData, filterIndex) =>
|
|
113
|
-
<
|
|
65
|
+
<Filter
|
|
114
66
|
key={filterIndex}
|
|
115
67
|
filterIndex={filterIndex}
|
|
116
68
|
onClick={digg(this, "onFilterClicked")}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import {digg, digs} from "diggerize"
|
|
2
|
+
import PropTypes from "prop-types"
|
|
3
|
+
import PropTypesExact from "prop-types-exact"
|
|
4
|
+
import {memo} from "react"
|
|
5
|
+
import Reflection from "../../base-model/reflection"
|
|
6
|
+
import {shapeComponent, ShapeComponent} from "set-state-compare/src/shape-component"
|
|
7
|
+
|
|
8
|
+
export default memo(shapeComponent(class ReflectionElement extends ShapeComponent {
|
|
9
|
+
static propTypes = PropTypesExact({
|
|
10
|
+
currentModelClass: PropTypes.func.isRequired,
|
|
11
|
+
onClick: PropTypes.func.isRequired,
|
|
12
|
+
reflection: PropTypes.instanceOf(Reflection).isRequired
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
render() {
|
|
16
|
+
const {currentModelClass, reflection} = digs(this.props, "currentModelClass", "reflection")
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<div
|
|
20
|
+
className="reflection-element"
|
|
21
|
+
data-model-class={currentModelClass.modelClassData().name}
|
|
22
|
+
data-reflection-name={reflection.name()}
|
|
23
|
+
onClick={digg(this, "onReflectionClicked")}
|
|
24
|
+
>
|
|
25
|
+
{currentModelClass.humanAttributeName(reflection.name())}
|
|
26
|
+
</div>
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
onReflectionClicked = (e) => {
|
|
31
|
+
e.preventDefault()
|
|
32
|
+
|
|
33
|
+
this.props.onClick({reflection: digg(this, "props", "reflection")})
|
|
34
|
+
}
|
|
35
|
+
}))
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import {digg} from "diggerize"
|
|
2
|
+
import PropTypes from "prop-types"
|
|
3
|
+
import {memo} from "react"
|
|
4
|
+
import {shapeComponent, ShapeComponent} from "set-state-compare/src/shape-component"
|
|
5
|
+
|
|
6
|
+
export default memo(shapeComponent(class ScopeElement extends ShapeComponent {
|
|
7
|
+
static defaultProps = {
|
|
8
|
+
active: false
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
static propTypes = {
|
|
12
|
+
active: PropTypes.bool.isRequired,
|
|
13
|
+
scope: PropTypes.object.isRequired
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
render() {
|
|
17
|
+
const {active, scope} = this.props
|
|
18
|
+
const style = {}
|
|
19
|
+
|
|
20
|
+
if (active) style.fontWeight = "bold"
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<div
|
|
24
|
+
className="scope-element"
|
|
25
|
+
key={scope.name()}
|
|
26
|
+
onClick={digg(this, "onScopeClicked")}
|
|
27
|
+
style={style}
|
|
28
|
+
>
|
|
29
|
+
{scope.name()}
|
|
30
|
+
</div>
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
onScopeClicked = (e) => {
|
|
35
|
+
e.preventDefault()
|
|
36
|
+
|
|
37
|
+
this.props.onScopeClicked({scope: this.props.scope})
|
|
38
|
+
}
|
|
39
|
+
}))
|
package/src/table/table.jsx
CHANGED
|
@@ -22,6 +22,7 @@ import TableSettings from "./table-settings"
|
|
|
22
22
|
import uniqunize from "uniqunize"
|
|
23
23
|
import useBreakpoint from "./use-breakpoint"
|
|
24
24
|
import useCollection from "../use-collection"
|
|
25
|
+
import useQueryParams from "on-location-changed/src/use-query-params.js"
|
|
25
26
|
|
|
26
27
|
const paginationOptions = [30, 60, 90, ["All", "all"]]
|
|
27
28
|
const WorkerPluginsCheckAllCheckbox = React.lazy(() => import("./worker-plugins-check-all-checkbox"))
|
|
@@ -79,6 +80,7 @@ export default memo(shapeComponent(class ApiMakerTable extends ShapeComponent {
|
|
|
79
80
|
|
|
80
81
|
setup() {
|
|
81
82
|
const {breakpoint} = useBreakpoint()
|
|
83
|
+
const queryParams = useQueryParams()
|
|
82
84
|
|
|
83
85
|
this.setInstance({
|
|
84
86
|
breakpoint,
|
|
@@ -91,18 +93,19 @@ export default memo(shapeComponent(class ApiMakerTable extends ShapeComponent {
|
|
|
91
93
|
if (!queryName) queryName = collectionKey
|
|
92
94
|
|
|
93
95
|
const columnsAsArray = this.columnsAsArray()
|
|
96
|
+
const querySName = `${queryName}_s`
|
|
94
97
|
|
|
95
98
|
this.useStates({
|
|
96
99
|
columns: columnsAsArray,
|
|
97
100
|
currentWorkplace: undefined,
|
|
98
|
-
identifier: this.props.identifier || `${collectionKey}-default`,
|
|
101
|
+
identifier: () => this.props.identifier || `${collectionKey}-default`,
|
|
99
102
|
preload: undefined,
|
|
100
103
|
preparedColumns: undefined,
|
|
101
104
|
queryName,
|
|
102
|
-
queryQName: `${queryName}_q`,
|
|
103
|
-
queryPageName: `${queryName}_page`,
|
|
104
|
-
querySName
|
|
105
|
-
showFilters:
|
|
105
|
+
queryQName: () => `${queryName}_q`,
|
|
106
|
+
queryPageName: () => `${queryName}_page`,
|
|
107
|
+
querySName,
|
|
108
|
+
showFilters: () => Boolean(queryParams[querySName]),
|
|
106
109
|
showSettings: false,
|
|
107
110
|
tableSetting: undefined,
|
|
108
111
|
tableSettingFullCacheKey: undefined
|