@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaspernj/api-maker",
3
- "version": "1.0.373",
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.42",
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.scheduleConnectUpcoming()
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
- scheduleConnectUpcoming () {
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
  }
@@ -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.flush()
30
+ pool.flushRunLast.run()
30
31
  } else {
31
- pool.setFlushTimeout()
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 flush() {
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
- // 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
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
  }
@@ -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 Attribute from "../../base-model/attribute"
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 React from "react"
8
- import Reflection from "../../base-model/reflection"
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 Shape from "set-state-compare/src/shape"
12
+ import {shapeComponent, ShapeComponent} from "set-state-compare/src/shape-component"
12
13
 
13
- class AttributeElement extends React.PureComponent {
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
- shape = new Shape(this, {
122
- attribute: this.currentModelClassFromPath(this.props.filter.p || []).ransackableAttributes().find((attribute) => attribute.name() == this.props.filter.a),
123
- path: this.props.filter.p || [],
124
- predicate: undefined,
125
- predicates: undefined,
126
- scope: this.props.filter.sc,
127
- value: this.props.filter.v
128
- })
129
- valueInputRef = React.createRef()
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
- componentDidMount() {
132
- this.loadRansackPredicates()
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.shape.set({
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.shape, "attribute", "predicate", "scope", "predicates", "value")
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.shape.attribute?.name()}
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.shape.scope?.name()}
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.shape.scope &&
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.shape, "path")
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.shape, "path")
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.shape.set({
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.shape.predicates.find((predicate) => predicate.name == chosenPredicateName)
201
+ const predicate = this.state.predicates.find((predicate) => predicate.name == chosenPredicateName)
297
202
 
298
- this.shape.set({predicate})
203
+ this.setState({predicate})
299
204
  }
300
205
 
301
206
  onReflectionClicked = ({reflection}) => {
302
- const newPath = this.shape.path.concat([inflection.underscore(reflection.name())])
207
+ const newPath = this.state.path.concat([inflection.underscore(reflection.name())])
303
208
 
304
- this.shape.set({
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.shape.set({
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.shape, "attribute", "path", "predicate", "scope")
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
- <ApiMakerTableFilter
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
+ }))
@@ -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: `${queryName}_s`,
105
- showFilters: false,
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