@kaspernj/api-maker 1.0.382 → 1.0.384

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.382",
3
+ "version": "1.0.384",
4
4
  "type": "module",
5
5
  "description": "",
6
6
  "main": "index.js",
@@ -169,7 +169,7 @@ export default class BaseModel {
169
169
  return foundReflection
170
170
  }
171
171
 
172
- static _token () {
172
+ static _token() {
173
173
  const csrfTokenElement = document.querySelector("meta[name='csrf-token']")
174
174
 
175
175
  if (csrfTokenElement) {
@@ -177,7 +177,7 @@ export default class BaseModel {
177
177
  }
178
178
  }
179
179
 
180
- constructor (args = {}) {
180
+ constructor(args = {}) {
181
181
  this.changes = {}
182
182
  this.newRecord = args.isNewRecord
183
183
  this.relationshipsCache = {}
@@ -197,7 +197,7 @@ export default class BaseModel {
197
197
  }
198
198
  }
199
199
 
200
- assignAttributes (newAttributes) {
200
+ assignAttributes(newAttributes) {
201
201
  for (const key in newAttributes) {
202
202
  const newValue = newAttributes[key]
203
203
  const attributeUnderscore = inflection.underscore(key)
@@ -225,7 +225,7 @@ export default class BaseModel {
225
225
  }
226
226
  }
227
227
 
228
- attributes () {
228
+ attributes() {
229
229
  const result = {}
230
230
 
231
231
  for (const key in this.modelData) {
@@ -239,7 +239,7 @@ export default class BaseModel {
239
239
  return result
240
240
  }
241
241
 
242
- can (givenAbilityName) {
242
+ can(givenAbilityName) {
243
243
  const abilityName = inflection.underscore(givenAbilityName)
244
244
 
245
245
  if (!(abilityName in this.abilities)) {
@@ -249,7 +249,7 @@ export default class BaseModel {
249
249
  return this.abilities[abilityName]
250
250
  }
251
251
 
252
- clone () {
252
+ clone() {
253
253
  const clone = new this.constructor()
254
254
 
255
255
  clone.abilities = {...this.abilities}
@@ -260,7 +260,7 @@ export default class BaseModel {
260
260
  return clone
261
261
  }
262
262
 
263
- cacheKey () {
263
+ cacheKey() {
264
264
  if (this.isPersisted()) {
265
265
  const keyParts = [
266
266
  this.modelClassData().paramKey,
@@ -297,11 +297,11 @@ export default class BaseModel {
297
297
  return cacheKeyGenerator.cacheKey()
298
298
  }
299
299
 
300
- static all () {
300
+ static all() {
301
301
  return this.ransack()
302
302
  }
303
303
 
304
- async create (attributes, options) {
304
+ async create(attributes, options) {
305
305
  if (attributes) this.assignAttributes(attributes)
306
306
  const paramKey = this.modelClassData().paramKey
307
307
  const modelData = this.getAttributes()
@@ -335,7 +335,7 @@ export default class BaseModel {
335
335
  return {model: this, response}
336
336
  }
337
337
 
338
- async createRaw (rawData, options = {}) {
338
+ async createRaw(rawData, options = {}) {
339
339
  const objectData = BaseModel._objectDataFromGivenRawData(rawData, options)
340
340
 
341
341
  let response
@@ -366,7 +366,7 @@ export default class BaseModel {
366
366
  return {model: this, response}
367
367
  }
368
368
 
369
- async destroy () {
369
+ async destroy() {
370
370
  const response = await CommandsPool.addCommand(
371
371
  {
372
372
  args: {query_params: this.collection && this.collection.params()},
@@ -390,7 +390,7 @@ export default class BaseModel {
390
390
  }
391
391
  }
392
392
 
393
- async ensureAbilities (listOfAbilities) {
393
+ async ensureAbilities(listOfAbilities) {
394
394
  // Populate an array with a list of abilities currently not loaded
395
395
  const abilitiesToLoad = []
396
396
 
@@ -425,16 +425,14 @@ export default class BaseModel {
425
425
  }
426
426
  }
427
427
 
428
- getAttributes () {
429
- return Object.assign(this.modelData, this.changes)
430
- }
428
+ getAttributes = () => Object.assign(this.modelData, this.changes)
431
429
 
432
- handleResponseError (response) {
430
+ handleResponseError(response) {
433
431
  BaseModel.parseValidationErrors({model: this, response})
434
432
  throw new new CustomError("Response wasn't successful", {model: this, response})
435
433
  }
436
434
 
437
- identifierKey () {
435
+ identifierKey() {
438
436
  if (!this._identifierKey) this._identifierKey = this.isPersisted() ? this.primaryKey() : this.uniqueKey()
439
437
 
440
438
  return this._identifierKey
@@ -446,13 +444,13 @@ export default class BaseModel {
446
444
  return false
447
445
  }
448
446
 
449
- isAssociationPresent (associationName) {
447
+ isAssociationPresent(associationName) {
450
448
  if (this.isAssociationLoaded(associationName)) return true
451
449
  if (associationName in this.relationships) return true
452
450
  return false
453
451
  }
454
452
 
455
- static parseValidationErrors ({error, model, options}) {
453
+ static parseValidationErrors({error, model, options}) {
456
454
  if (!(error instanceof ValidationError)) return
457
455
  if (!error.args.response.validation_errors) return
458
456
 
@@ -468,7 +466,7 @@ export default class BaseModel {
468
466
  }
469
467
  }
470
468
 
471
- static humanAttributeName (attributeName) {
469
+ static humanAttributeName(attributeName) {
472
470
  const keyName = digg(this.modelClassData(), "i18nKey")
473
471
  const i18n = Config.getI18n()
474
472
 
@@ -477,7 +475,7 @@ export default class BaseModel {
477
475
  return inflection.humanize(attributeName)
478
476
  }
479
477
 
480
- isAttributeChanged (attributeName) {
478
+ isAttributeChanged(attributeName) {
481
479
  const attributeNameUnderscore = inflection.underscore(attributeName)
482
480
  const attributeData = this.modelClassData().attributes.find((attribute) => digg(attribute, "name") == attributeNameUnderscore)
483
481
 
@@ -500,7 +498,7 @@ export default class BaseModel {
500
498
  return changedMethod(oldValue, newValue)
501
499
  }
502
500
 
503
- isChanged () {
501
+ isChanged() {
504
502
  const keys = Object.keys(this.changes)
505
503
 
506
504
  if (keys.length > 0) {
@@ -510,7 +508,7 @@ export default class BaseModel {
510
508
  }
511
509
  }
512
510
 
513
- isNewRecord () {
511
+ isNewRecord() {
514
512
  if (this.newRecord !== undefined) {
515
513
  return this.newRecord
516
514
  } else if ("id" in this.modelData && this.modelData.id) {
@@ -520,15 +518,11 @@ export default class BaseModel {
520
518
  }
521
519
  }
522
520
 
523
- isPersisted () {
524
- return !this.isNewRecord()
525
- }
521
+ isPersisted = () => !this.isNewRecord()
526
522
 
527
- static snakeCase (string) {
528
- return inflection.underscore(string)
529
- }
523
+ static snakeCase = (string) => inflection.underscore(string)
530
524
 
531
- savedChangeToAttribute (attributeName) {
525
+ savedChangeToAttribute(attributeName) {
532
526
  if (!this.previousModelData)
533
527
  return false
534
528
 
@@ -554,7 +548,7 @@ export default class BaseModel {
554
548
  return changedMethod(oldValue, newValue)
555
549
  }
556
550
 
557
- setNewModel (model) {
551
+ setNewModel(model) {
558
552
  this.setNewModelData(model)
559
553
 
560
554
  for(const relationshipName in model.relationships) {
@@ -566,7 +560,7 @@ export default class BaseModel {
566
560
  }
567
561
  }
568
562
 
569
- setNewModelData (model) {
563
+ setNewModelData(model) {
570
564
  if (!("modelData" in model)) throw new Error(`No modelData in model: ${JSON.stringify(model)}`)
571
565
 
572
566
  this.previousModelData = Object.assign({}, digg(this, "modelData"))
@@ -576,12 +570,12 @@ export default class BaseModel {
576
570
  }
577
571
  }
578
572
 
579
- _isDateChanged (oldValue, newValue) {
573
+ _isDateChanged(oldValue, newValue) {
580
574
  if (Date.parse(oldValue) != Date.parse(newValue))
581
575
  return true
582
576
  }
583
577
 
584
- _isIntegerChanged (oldValue, newValue) {
578
+ _isIntegerChanged(oldValue, newValue) {
585
579
  if (parseInt(oldValue, 10) != parseInt(newValue, 10))
586
580
  return true
587
581
  }
@@ -594,11 +588,9 @@ export default class BaseModel {
594
588
  return true
595
589
  }
596
590
 
597
- modelClassData () {
598
- return this.constructor.modelClassData()
599
- }
591
+ modelClassData = () => this.constructor.modelClassData()
600
592
 
601
- async reload () {
593
+ async reload() {
602
594
  const params = this.collection && this.collection.params()
603
595
  const ransackParams = {}
604
596
  ransackParams[`${this.constructor.primaryKey()}_eq`] = this.primaryKey()
@@ -624,7 +616,7 @@ export default class BaseModel {
624
616
  this.changes = {}
625
617
  }
626
618
 
627
- save () {
619
+ save() {
628
620
  if (this.isNewRecord()) {
629
621
  return this.create()
630
622
  } else {
@@ -632,7 +624,7 @@ export default class BaseModel {
632
624
  }
633
625
  }
634
626
 
635
- saveRaw (rawData, options = {}) {
627
+ saveRaw(rawData, options = {}) {
636
628
  if (this.isNewRecord()) {
637
629
  return this.createRaw(rawData, options)
638
630
  } else {
@@ -640,9 +632,10 @@ export default class BaseModel {
640
632
  }
641
633
  }
642
634
 
643
- async update (newAttributes, options) {
644
- if (newAttributes)
635
+ async update(newAttributes, options) {
636
+ if (newAttributes) {
645
637
  this.assignAttributes(newAttributes)
638
+ }
646
639
 
647
640
  if (Object.keys(this.changes).length == 0) {
648
641
  return {model: this}
@@ -685,7 +678,7 @@ export default class BaseModel {
685
678
  }
686
679
  }
687
680
 
688
- _refreshModelFromResponse (response) {
681
+ _refreshModelFromResponse(response) {
689
682
  let newModel = digg(response, "model")
690
683
 
691
684
  if (Array.isArray(newModel)) newModel = newModel[0]
@@ -693,7 +686,7 @@ export default class BaseModel {
693
686
  this.setNewModel(newModel)
694
687
  }
695
688
 
696
- _refreshModelDataFromResponse (response) {
689
+ _refreshModelDataFromResponse(response) {
697
690
  let newModel = digg(response, "model")
698
691
 
699
692
  if (Array.isArray(newModel)) newModel = newModel[0]
@@ -701,7 +694,7 @@ export default class BaseModel {
701
694
  this.setNewModelData(newModel)
702
695
  }
703
696
 
704
- static _objectDataFromGivenRawData (rawData, options) {
697
+ static _objectDataFromGivenRawData(rawData, options) {
705
698
  if (rawData instanceof FormData || rawData.nodeName == "FORM") {
706
699
  const formData = FormDataObjectizer.formDataFromObject(rawData, options)
707
700
 
@@ -711,7 +704,7 @@ export default class BaseModel {
711
704
  return rawData
712
705
  }
713
706
 
714
- async updateRaw (rawData, options = {}) {
707
+ async updateRaw(rawData, options = {}) {
715
708
  const objectData = BaseModel._objectDataFromGivenRawData(rawData, options)
716
709
  let response
717
710
 
@@ -743,11 +736,11 @@ export default class BaseModel {
743
736
  return {response, model: this}
744
737
  }
745
738
 
746
- isValid () {
739
+ isValid() {
747
740
  throw new Error("Not implemented yet")
748
741
  }
749
742
 
750
- async isValidOnServer () {
743
+ async isValidOnServer() {
751
744
  const modelData = this.getAttributes()
752
745
  const paramKey = this.modelClassData().paramKey
753
746
  const dataToUse = {}
@@ -771,7 +764,7 @@ export default class BaseModel {
771
764
 
772
765
  modelClass = () => this.constructor
773
766
 
774
- preloadRelationship (relationshipName, model) {
767
+ preloadRelationship(relationshipName, model) {
775
768
  this.relationshipsCache[BaseModel.snakeCase(relationshipName)] = model
776
769
  this.relationships[BaseModel.snakeCase(relationshipName)] = model
777
770
  }
@@ -782,7 +775,7 @@ export default class BaseModel {
782
775
 
783
776
  markedForDestruction = () => this._markedForDestruction
784
777
 
785
- uniqueKey () {
778
+ uniqueKey() {
786
779
  if (!this.uniqueKeyValue) {
787
780
  const min = 5000000000000000
788
781
  const max = 9007199254740991
@@ -793,7 +786,7 @@ export default class BaseModel {
793
786
  return this.uniqueKeyValue
794
787
  }
795
788
 
796
- static async _callCollectionCommand (args, commandArgs) {
789
+ static async _callCollectionCommand(args, commandArgs) {
797
790
  const formOrDataObject = args.args
798
791
 
799
792
  try {
@@ -815,7 +808,7 @@ export default class BaseModel {
815
808
 
816
809
  _callMemberCommand = (args, commandArgs) => CommandsPool.addCommand(args, commandArgs)
817
810
 
818
- static _postDataFromArgs (args) {
811
+ static _postDataFromArgs(args) {
819
812
  let postData
820
813
 
821
814
  if (args) {
@@ -831,13 +824,13 @@ export default class BaseModel {
831
824
  return postData
832
825
  }
833
826
 
834
- readAttribute (attributeName) {
827
+ readAttribute(attributeName) {
835
828
  const attributeNameUnderscore = inflection.underscore(attributeName)
836
829
 
837
830
  return this.readAttributeUnderscore(attributeNameUnderscore)
838
831
  }
839
832
 
840
- readAttributeUnderscore (attributeName) {
833
+ readAttributeUnderscore(attributeName) {
841
834
  if (attributeName in this.changes) {
842
835
  return this.changes[attributeName]
843
836
  } else if (attributeName in this.modelData) {
@@ -854,7 +847,7 @@ export default class BaseModel {
854
847
  }
855
848
  }
856
849
 
857
- isAttributeLoaded (attributeName) {
850
+ isAttributeLoaded(attributeName) {
858
851
  const attributeNameUnderscore = inflection.underscore(attributeName)
859
852
 
860
853
  if (attributeNameUnderscore in this.changes) return true
@@ -862,7 +855,7 @@ export default class BaseModel {
862
855
  return false
863
856
  }
864
857
 
865
- _isPresent (value) {
858
+ _isPresent(value) {
866
859
  if (!value) {
867
860
  return false
868
861
  } else if (typeof value == "string" && value.match(/^\s*$/)) {
@@ -872,7 +865,7 @@ export default class BaseModel {
872
865
  return true
873
866
  }
874
867
 
875
- async _loadBelongsToReflection (args, queryArgs = {}) {
868
+ async _loadBelongsToReflection(args, queryArgs = {}) {
876
869
  if (args.reflectionName in this.relationships) {
877
870
  return this.relationships[args.reflectionName]
878
871
  } else if (args.reflectionName in this.relationshipsCache) {
@@ -885,7 +878,7 @@ export default class BaseModel {
885
878
  }
886
879
  }
887
880
 
888
- _readBelongsToReflection ({reflectionName}) {
881
+ _readBelongsToReflection({reflectionName}) {
889
882
  if (reflectionName in this.relationships) {
890
883
  return this.relationships[reflectionName]
891
884
  } else if (reflectionName in this.relationshipsCache) {
@@ -900,7 +893,7 @@ export default class BaseModel {
900
893
  throw new NotLoadedError(`${modelClassName}#${reflectionName} hasn't been loaded yet. Only these were loaded: ${loadedRelationships.join(", ")}`)
901
894
  }
902
895
 
903
- async _loadHasManyReflection (args, queryArgs = {}) {
896
+ async _loadHasManyReflection(args, queryArgs = {}) {
904
897
  if (args.reflectionName in this.relationships) {
905
898
  return this.relationships[args.reflectionName]
906
899
  } else if (args.reflectionName in this.relationshipsCache) {
@@ -915,7 +908,7 @@ export default class BaseModel {
915
908
  return models
916
909
  }
917
910
 
918
- async _loadHasOneReflection (args, queryArgs = {}) {
911
+ async _loadHasOneReflection(args, queryArgs = {}) {
919
912
  if (args.reflectionName in this.relationships) {
920
913
  return this.relationships[args.reflectionName]
921
914
  } else if (args.reflectionName in this.relationshipsCache) {
@@ -930,7 +923,7 @@ export default class BaseModel {
930
923
  }
931
924
  }
932
925
 
933
- _readHasOneReflection ({reflectionName}) {
926
+ _readHasOneReflection({reflectionName}) {
934
927
  if (reflectionName in this.relationships) {
935
928
  return this.relationships[reflectionName]
936
929
  } else if (reflectionName in this.relationshipsCache) {
@@ -947,14 +940,14 @@ export default class BaseModel {
947
940
  throw new NotLoadedError(`${modelClassName}#${reflectionName} hasn't been loaded yet. Only these were loaded: ${loadedRelationships.join(", ")}`)
948
941
  }
949
942
 
950
- _readModelDataFromArgs (args) {
943
+ _readModelDataFromArgs(args) {
951
944
  this.abilities = args.data.b || {}
952
945
  this.collection = args.collection
953
946
  this.modelData = objectToUnderscore(args.data.a)
954
947
  this.preloadedRelationships = args.data.r
955
948
  }
956
949
 
957
- _readPreloadedRelationships (preloaded) {
950
+ _readPreloadedRelationships(preloaded) {
958
951
  if (!this.preloadedRelationships) {
959
952
  return
960
953
  }
@@ -21,12 +21,12 @@ export default memo(shapeComponent(class ApiMakerBootstrapPaginate extends BaseC
21
21
  const {result} = this.p
22
22
 
23
23
  this.totalPages = useMemo(
24
- () => Math.ceil(this.p.result.count() / this.p.result.perPage()),
25
- [result.currentPage(), result.totalCount(), result.totalPages()]
24
+ () => Math.ceil(result.count() / result.perPage()),
25
+ [result.count(), result.perPage()]
26
26
  )
27
27
  this.pages = useMemo(
28
28
  () => this.calculatePages(),
29
- [result.currentPage(), result.totalCount(), result.totalPages()]
29
+ [result.currentPage(), this.totalPages]
30
30
  )
31
31
  }
32
32
 
@@ -1,6 +1,6 @@
1
1
  import Collection from "./collection.mjs"
2
2
  import {digg} from "diggerize"
3
- import {memo, useEffect} from "react"
3
+ import {memo, useMemo} from "react"
4
4
  import PropTypes from "prop-types"
5
5
  import PropTypesExact from "prop-types-exact"
6
6
  import useCollection from "./use-collection"
@@ -30,7 +30,7 @@ const CollectionLoader = ({component, ...restProps}) => {
30
30
 
31
31
  s.updateMeta({component, useCollectionResult})
32
32
 
33
- useEffect(() => {
33
+ useMemo(() => {
34
34
  s.m.component.setState(s.m.useCollectionResult)
35
35
  }, cacheParts)
36
36
 
@@ -3,7 +3,7 @@ import {digg} from "diggerize"
3
3
  import * as inflection from "inflection"
4
4
  import {Pressable, Text, TextInput, View} from "react-native"
5
5
  import Locales from "shared/locales"
6
- import {memo, useCallback, useEffect, useMemo, useState} from "react"
6
+ import {memo, useCallback, useMemo, useState} from "react"
7
7
  import useCurrentUser from "../use-current-user"
8
8
  import useModel from "../use-model"
9
9
  import useQueryParams from "on-location-changed/src/use-query-params"
@@ -16,7 +16,7 @@ const EditAttributeInput = memo(({attributeName, id, inputs, label, model, name}
16
16
  const defaultValue = useCallback(() => model[attributeName]() || "")
17
17
  const [value, setValue] = useState(() => defaultValue())
18
18
 
19
- useEffect(() => {
19
+ useMemo(() => {
20
20
  inputs[name] = value
21
21
  }, [])
22
22
 
@@ -55,7 +55,7 @@ const EditAttributeContent = memo(({attribute, id, inputs, model, name}) => {
55
55
  inputs[name] = newValue
56
56
  setValue(newValue)
57
57
  })
58
- useEffect(() => {
58
+ useMemo(() => {
59
59
  inputs[name] = value
60
60
  }, [])
61
61
 
@@ -10,7 +10,6 @@ import {shapeComponent} from "set-state-compare/src/shape-component.js"
10
10
  import ShowPage from "./show-page"
11
11
  import ShowReflectionActions from "./show-reflection-actions"
12
12
  import ShowReflectionPage from "./show-reflection-page"
13
- import {useEffect} from "react"
14
13
  import useCanCan from "../use-can-can"
15
14
  import useCurrentUser from "../use-current-user.mjs"
16
15
  import useQueryParams from "on-location-changed/src/use-query-params"
@@ -43,7 +42,7 @@ export default memo(shapeComponent(class ApiMakerSuperAdmin extends BaseComponen
43
42
  this.useStates({
44
43
  model: undefined
45
44
  })
46
- useEffect(
45
+ useMemo(
47
46
  () => { this.loadModel() },
48
47
  [this.modelId]
49
48
  )
@@ -6,7 +6,7 @@ import Header from "./header"
6
6
  import Menu from "./menu"
7
7
  import PropTypes from "prop-types"
8
8
  import PropTypesExact from "prop-types-exact"
9
- import {memo, useCallback, useEffect} from "react"
9
+ import {memo, useCallback, useMemo} from "react"
10
10
  import useCurrentUser from "../../use-current-user"
11
11
  import useShape from "set-state-compare/src/use-shape.js"
12
12
 
@@ -26,7 +26,7 @@ const ApiMakerSuperAdminLayout = ({
26
26
  const s = useShape()
27
27
  const currentUser = useCurrentUser()
28
28
 
29
- useEffect(() => {
29
+ useMemo(() => {
30
30
  CommandsPool.current().globalRequestData.layout = "admin"
31
31
  CommandsPool.current().globalRequestData.locale = I18n.locale
32
32
  }, [I18n.locale])
@@ -1,12 +1,13 @@
1
1
  import Attribute from "../../base-model/attribute"
2
+ import BaseComponent from "../../base-component"
2
3
  import {digg, digs} from "diggerize"
3
4
  import * as inflection from "inflection"
4
5
  import PropTypes from "prop-types"
5
6
  import PropTypesExact from "prop-types-exact"
6
7
  import {memo} from "react"
7
- import {shapeComponent, ShapeComponent} from "set-state-compare/src/shape-component"
8
+ import {shapeComponent} from "set-state-compare/src/shape-component"
8
9
 
9
- export default memo(shapeComponent(class AttributeElement extends ShapeComponent {
10
+ export default memo(shapeComponent(class AttributeElement extends BaseComponent {
10
11
  static propTypes = PropTypesExact({
11
12
  active: PropTypes.bool.isRequired,
12
13
  attribute: PropTypes.instanceOf(Attribute).isRequired,
@@ -16,7 +17,7 @@ export default memo(shapeComponent(class AttributeElement extends ShapeComponent
16
17
  })
17
18
 
18
19
  render() {
19
- const {active, attribute, currentModelClass} = digs(this.props, "active", "attribute", "currentModelClass")
20
+ const {active, attribute, currentModelClass} = this.p
20
21
  const style = {}
21
22
 
22
23
  if (active) style.fontWeight = "bold"
@@ -37,6 +38,6 @@ export default memo(shapeComponent(class AttributeElement extends ShapeComponent
37
38
  onAttributeClicked = (e) => {
38
39
  e.preventDefault()
39
40
 
40
- this.props.onClick({attribute: digg(this, "props", "attribute")})
41
+ this.p.onClick({attribute: this.p.attribute})
41
42
  }
42
43
  }))
@@ -1,10 +1,11 @@
1
- import {digg, digs} from "diggerize"
1
+ import BaseComponent from "../../base-component"
2
+ import {digg} from "diggerize"
2
3
  import PropTypes from "prop-types"
3
4
  import PropTypesExact from "prop-types-exact"
4
5
  import {memo} from "react"
5
- import {shapeComponent, ShapeComponent} from "set-state-compare/src/shape-component"
6
+ import {shapeComponent} from "set-state-compare/src/shape-component"
6
7
 
7
- export default memo(shapeComponent(class ApiMakerTableFilter extends ShapeComponent {
8
+ export default memo(shapeComponent(class ApiMakerTableFilter extends BaseComponent {
8
9
  static propTypes = PropTypesExact({
9
10
  a: PropTypes.string,
10
11
  filterIndex: PropTypes.number.isRequired,
@@ -17,7 +18,7 @@ export default memo(shapeComponent(class ApiMakerTableFilter extends ShapeCompon
17
18
  })
18
19
 
19
20
  render() {
20
- const {p, v} = digs(this.props, "p", "v")
21
+ const {p, v} = this.p
21
22
  const {a, pre, sc} = this.props
22
23
 
23
24
  return (
@@ -40,7 +41,7 @@ export default memo(shapeComponent(class ApiMakerTableFilter extends ShapeCompon
40
41
  onFilterClicked = (e) => {
41
42
  e.preventDefault()
42
43
 
43
- const {a, filterIndex, p, pre, v} = digs(this.props, "a", "filterIndex", "p", "pre", "v")
44
+ const {a, filterIndex, p, pre, v} = this.p
44
45
 
45
46
  this.props.onClick({a, filterIndex, p, pre, v})
46
47
  }
@@ -48,7 +49,7 @@ export default memo(shapeComponent(class ApiMakerTableFilter extends ShapeCompon
48
49
  onRemoveFilterClicked = (e) => {
49
50
  e.preventDefault()
50
51
 
51
- const {filterIndex} = digs(this.props, "filterIndex")
52
+ const {filterIndex} = this.p
52
53
 
53
54
  this.props.onRemoveClicked({filterIndex})
54
55
  }
@@ -1,13 +1,14 @@
1
1
  import apiMakerConfig from "@kaspernj/api-maker/src/config.mjs"
2
+ import BaseComponent from "../../base-component"
2
3
  import classNames from "classnames"
3
4
  import {digg} from "diggerize"
4
- import {memo, useEffect} from "react"
5
- import {shapeComponent, ShapeComponent} from "set-state-compare/src/shape-component.js"
5
+ import {memo, useMemo} from "react"
6
+ import {shapeComponent} from "set-state-compare/src/shape-component.js"
6
7
  import {TableSearch} from "../../models.mjs.erb"
7
8
  import {Pressable, Text, View} from "react-native"
8
9
  import useI18n from "i18n-on-steroids/src/use-i18n.mjs"
9
10
 
10
- const SearchLink = memo(shapeComponent(class SearchLink extends ShapeComponent {
11
+ const SearchLink = memo(shapeComponent(class SearchLink extends BaseComponent {
11
12
  render() {
12
13
  const {search} = this.props
13
14
 
@@ -76,7 +77,7 @@ const SearchLink = memo(shapeComponent(class SearchLink extends ShapeComponent {
76
77
  onSearchClicked = () => this.props.onClick({search: this.props.search})
77
78
  }))
78
79
 
79
- export default memo(shapeComponent(class ApiMakerTableFiltersLoadSearchModal extends ShapeComponent {
80
+ export default memo(shapeComponent(class ApiMakerTableFiltersLoadSearchModal extends BaseComponent {
80
81
  setup() {
81
82
  const {t} = useI18n({namespace: "js.api_maker.table.filters.load_search_modal"})
82
83
 
@@ -86,7 +87,7 @@ export default memo(shapeComponent(class ApiMakerTableFiltersLoadSearchModal ext
86
87
  })
87
88
  this.setInstance({t})
88
89
 
89
- useEffect(() => {
90
+ useMemo(() => {
90
91
  this.loadSearches()
91
92
  }, [])
92
93
  }
@@ -1,11 +1,12 @@
1
+ import BaseComponent from "../../base-component"
1
2
  import {digg, digs} from "diggerize"
2
3
  import PropTypes from "prop-types"
3
4
  import PropTypesExact from "prop-types-exact"
4
5
  import {memo} from "react"
5
6
  import Reflection from "../../base-model/reflection"
6
- import {shapeComponent, ShapeComponent} from "set-state-compare/src/shape-component"
7
+ import {shapeComponent} from "set-state-compare/src/shape-component"
7
8
 
8
- export default memo(shapeComponent(class ReflectionElement extends ShapeComponent {
9
+ export default memo(shapeComponent(class ReflectionElement extends BaseComponent {
9
10
  static propTypes = PropTypesExact({
10
11
  currentModelClass: PropTypes.func.isRequired,
11
12
  onClick: PropTypes.func.isRequired,
@@ -13,7 +14,7 @@ export default memo(shapeComponent(class ReflectionElement extends ShapeComponen
13
14
  })
14
15
 
15
16
  render() {
16
- const {currentModelClass, reflection} = digs(this.props, "currentModelClass", "reflection")
17
+ const {currentModelClass, reflection} = this.p
17
18
 
18
19
  return (
19
20
  <div
@@ -30,6 +31,6 @@ export default memo(shapeComponent(class ReflectionElement extends ShapeComponen
30
31
  onReflectionClicked = (e) => {
31
32
  e.preventDefault()
32
33
 
33
- this.props.onClick({reflection: digg(this, "props", "reflection")})
34
+ this.p.onClick({reflection: digg(this, "props", "reflection")})
34
35
  }
35
36
  }))
@@ -1,12 +1,13 @@
1
1
  import apiMakerConfig from "@kaspernj/api-maker/src/config.mjs"
2
- import Checkbox from "@kaspernj/api-maker/src/bootstrap/checkbox"
2
+ import BaseComponent from "../../base-component"
3
+ import Checkbox from "../../bootstrap/checkbox"
3
4
  import {digg, digs} from "diggerize"
4
5
  import Input from "../../bootstrap/input"
5
- import {shapeComponent, ShapeComponent} from "set-state-compare/src/shape-component.js"
6
+ import {shapeComponent} from "set-state-compare/src/shape-component.js"
6
7
  import {memo} from "react"
7
8
  import useI18n from "i18n-on-steroids/src/use-i18n.mjs"
8
9
 
9
- export default memo(shapeComponent(class ApiMakerTableFiltersSaveSearchModal extends ShapeComponent {
10
+ export default memo(shapeComponent(class ApiMakerTableFiltersSaveSearchModal extends BaseComponent {
10
11
  setup() {
11
12
  const {t} = useI18n({namespace: "js.api_maker.table.filters.save_search_modal"})
12
13
 
@@ -45,7 +46,7 @@ export default memo(shapeComponent(class ApiMakerTableFiltersSaveSearchModal ext
45
46
 
46
47
  const form = digg(e, "target")
47
48
  const formData = new FormData(form)
48
- const {currentFilters, currentUser, onRequestClose, search} = digs(this.props, "currentFilters", "currentUser", "onRequestClose", "search")
49
+ const {currentFilters, currentUser, onRequestClose, search} = this.p
49
50
 
50
51
  if (search.isNewRecord()) {
51
52
  formData.append("table_search[query_params]", JSON.stringify(currentFilters()))
@@ -1,20 +1,22 @@
1
+ import BaseComponent from "../../base-component"
1
2
  import {digg} from "diggerize"
2
3
  import PropTypes from "prop-types"
3
4
  import {memo} from "react"
4
- import {shapeComponent, ShapeComponent} from "set-state-compare/src/shape-component"
5
+ import {shapeComponent} from "set-state-compare/src/shape-component"
5
6
 
6
- export default memo(shapeComponent(class ScopeElement extends ShapeComponent {
7
+ export default memo(shapeComponent(class ScopeElement extends BaseComponent {
7
8
  static defaultProps = {
8
9
  active: false
9
10
  }
10
11
 
11
12
  static propTypes = {
12
13
  active: PropTypes.bool.isRequired,
14
+ onScopeClicked: PropTypes.func.isRequired,
13
15
  scope: PropTypes.object.isRequired
14
16
  }
15
17
 
16
18
  render() {
17
- const {active, scope} = this.props
19
+ const {active, scope} = this.p
18
20
  const style = {}
19
21
 
20
22
  if (active) style.fontWeight = "bold"
@@ -34,6 +36,6 @@ export default memo(shapeComponent(class ScopeElement extends ShapeComponent {
34
36
  onScopeClicked = (e) => {
35
37
  e.preventDefault()
36
38
 
37
- this.props.onScopeClicked({scope: this.props.scope})
39
+ this.p.onScopeClicked({scope: this.p.scope})
38
40
  }
39
41
  }))
@@ -38,6 +38,14 @@ export default memo(shapeComponent(class ApiMakerTableHeaderColumn extends BaseC
38
38
  const {defaultParams} = table.props
39
39
  const {query} = digs(table.collection, "query")
40
40
  const ColumnInHeadComponent = table.columnInHeadComponent()
41
+ let sortLinkStyle
42
+ let textProps = {}
43
+
44
+ if (fixedTableLayout) {
45
+ sortLinkStyle = {whiteSpace: "nowrap", overflow: "hidden"}
46
+ textProps.ellipsizeMode="clip"
47
+ textProps.numberOfLines = 1
48
+ }
41
49
 
42
50
  return (
43
51
  <ColumnInHeadComponent
@@ -49,10 +57,16 @@ export default memo(shapeComponent(class ApiMakerTableHeaderColumn extends BaseC
49
57
  >
50
58
  <View style={{display: "flex", flexDirection: "row", alignItems: "center"}}>
51
59
  {tableSettingColumn.hasSortKey() && query &&
52
- <SortLink attribute={tableSettingColumn.sortKey()} defaultParams={defaultParams} query={query} title={table.headerLabelForColumn(column)} />
60
+ <SortLink
61
+ attribute={tableSettingColumn.sortKey()}
62
+ defaultParams={defaultParams}
63
+ query={query}
64
+ style={sortLinkStyle}
65
+ title={table.headerLabelForColumn(column)}
66
+ />
53
67
  }
54
68
  {(!tableSettingColumn.hasSortKey() || !query) &&
55
- <Text>
69
+ <Text {...textProps}>
56
70
  {table.headerLabelForColumn(column)}
57
71
  </Text>
58
72
  }
@@ -56,7 +56,7 @@ export default memo(shapeComponent(class ApiMakerTableSettings extends BaseCompo
56
56
  }
57
57
 
58
58
  onFixedTableChecked = async (checked) => {
59
- await this.tableSetting().update({fixedTableLayout: true})
59
+ await this.tableSetting().update({fixed_table_layout: checked})
60
60
  this.setState({fixedTableLayout: checked})
61
61
  this.p.onFixedTableLayoutChanged(checked)
62
62
  }
@@ -14,7 +14,7 @@ import ModelRow from "./model-row"
14
14
  import Paginate from "../bootstrap/paginate"
15
15
  import Params from "../params"
16
16
  import PropTypes from "prop-types"
17
- import React, {memo, useEffect, useRef} from "react"
17
+ import React, {memo, useMemo, useRef} from "react"
18
18
  import selectCalculator from "./select-calculator"
19
19
  import Select from "../inputs/select"
20
20
  import Settings from "./settings"
@@ -113,7 +113,7 @@ export default memo(shapeComponent(class ApiMakerTable extends BaseComponent {
113
113
  tableSettingFullCacheKey: undefined
114
114
  })
115
115
 
116
- useEffect(() => {
116
+ useMemo(() => {
117
117
  this.loadTableSetting()
118
118
 
119
119
  if (this.props.workplace) this.loadCurrentWorkplace()
@@ -1,4 +1,4 @@
1
- import {useCallback, useEffect} from "react"
1
+ import {useCallback, useLayoutEffect} from "react"
2
2
  import apiMakerConfig from "@kaspernj/api-maker/src/config.mjs"
3
3
  import useShape from "set-state-compare/src/use-shape.js"
4
4
 
@@ -30,7 +30,7 @@ const useBreakpoint = () => {
30
30
  breakpoint: () => calculateBreakPoint()
31
31
  })
32
32
 
33
- useEffect(() => {
33
+ useLayoutEffect(() => {
34
34
  window.addEventListener("resize", onCalled)
35
35
 
36
36
  return () => {
@@ -4,7 +4,7 @@ import EventConnection from "../event-connection"
4
4
  import modelClassRequire from "../model-class-require.mjs"
5
5
  import PropTypes from "prop-types"
6
6
  import PropTypesExact from "prop-types-exact"
7
- import {memo, useEffect} from "react"
7
+ import {memo, useMemo} from "react"
8
8
  import {shapeComponent, ShapeComponent} from "set-state-compare/src/shape-component"
9
9
 
10
10
  const Workplace = modelClassRequire("Workplace")
@@ -21,7 +21,7 @@ export default memo(shapeComponent(class ApiMakerTableWorkerPluginsCheckbox exte
21
21
  linkLoaded: false
22
22
  })
23
23
 
24
- useEffect(() => {
24
+ useMemo(() => {
25
25
  this.loadCurrentLink()
26
26
  }, [])
27
27
  }
@@ -1,5 +1,5 @@
1
1
  import CanCan from "./can-can.mjs"
2
- import {useCallback, useEffect, useState} from "react"
2
+ import {useCallback, useLayoutEffect, useMemo, useState} from "react"
3
3
  import useCurrentUser from "./use-current-user.mjs"
4
4
  import useShape from "set-state-compare/src/use-shape.js"
5
5
 
@@ -26,12 +26,12 @@ const useCanCan = (abilitiesCallback, dependencies) => {
26
26
  loadAbilities()
27
27
  }, [])
28
28
 
29
- useEffect(() => {
29
+ useMemo(() => {
30
30
  setCanCan(undefined)
31
31
  loadAbilities()
32
32
  }, dependencies)
33
33
 
34
- useEffect(() => {
34
+ useLayoutEffect(() => {
35
35
  CanCan.current().events.addListener("onResetAbilities", onResetAbilities)
36
36
 
37
37
  return () => {
@@ -2,7 +2,8 @@ import debounce from "debounce"
2
2
  import {digg} from "diggerize"
3
3
  import * as inflection from "inflection"
4
4
  import ModelEvents from "./model-events.mjs"
5
- import {useCallback, useEffect} from "react"
5
+ import {useCallback, useLayoutEffect, useMemo} from "react"
6
+ import useCreatedEvent from "./use-created-event.mjs"
6
7
  import useShape from "set-state-compare/src/use-shape.js"
7
8
  import useQueryParams from "on-location-changed/src/use-query-params.js"
8
9
 
@@ -64,7 +65,7 @@ const useCollection = (props, cacheKeys = []) => {
64
65
  showNoRecordsFoundContent: false
65
66
  })
66
67
  s.useStates({
67
- qParams: qParams()
68
+ qParams: () => qParams()
68
69
  })
69
70
 
70
71
  let modelIdsCacheString
@@ -221,7 +222,11 @@ const useCollection = (props, cacheKeys = []) => {
221
222
  if (models.length === 0 && s.props.noRecordsFoundContent) return true
222
223
  }, [])
223
224
 
224
- useEffect(
225
+ const onCreated = useCallback(() => {
226
+ loadModels()
227
+ }, [])
228
+
229
+ useMemo(
225
230
  () => {
226
231
  if (!("ifCondition" in s.props) || s.props.ifCondition) {
227
232
  loadQParams()
@@ -238,23 +243,15 @@ const useCollection = (props, cacheKeys = []) => {
238
243
  ].concat(cacheKeys)
239
244
  )
240
245
 
241
- useEffect(() => {
242
- if (s.props.noRecordsAvailableContent) loadOverallCount()
243
- }, [])
244
-
245
- const onCreated = useCallback(() => {
246
- loadModels()
247
- }, [])
248
-
249
- useEffect(() => {
250
- const connectCreated = ModelEvents.connectCreated(s.p.modelClass, onCreated)
251
-
252
- return () => {
253
- connectCreated.unsubscribe()
246
+ useMemo(() => {
247
+ if (s.props.noRecordsAvailableContent) {
248
+ loadOverallCount()
254
249
  }
255
250
  }, [])
256
251
 
257
- useEffect(() => {
252
+ useCreatedEvent(s.p.modelClass, onCreated)
253
+
254
+ useLayoutEffect(() => {
258
255
  const connections = []
259
256
 
260
257
  if (s.s.models) {
@@ -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} from "react"
5
+ import {useCallback, useLayoutEffect} from "react"
6
6
  import useShape from "set-state-compare/src/use-shape.js"
7
7
 
8
8
  const ApiMakerUseCreatedEvent = (modelClass, onCreated, args = {}) => {
@@ -33,7 +33,7 @@ const ApiMakerUseCreatedEvent = (modelClass, onCreated, args = {}) => {
33
33
  }
34
34
  }, [])
35
35
 
36
- useEffect(() => {
36
+ useLayoutEffect(() => {
37
37
  const connectCreated = ModelEvents.connectCreated(s.p.modelClass, (...args) => onCreatedCallback(...args))
38
38
 
39
39
  return () => {
@@ -1,4 +1,4 @@
1
- import {useCallback, useEffect, useMemo} from "react"
1
+ import {useCallback, useMemo} from "react"
2
2
  import {camelize} from "inflection"
3
3
  import Devise from "./devise.mjs"
4
4
  import Logger from "./logger.mjs"
@@ -69,7 +69,7 @@ const useCurrentUser = (args) => {
69
69
  s.set(setStatesArgument)
70
70
  }, [])
71
71
 
72
- useEffect(() => {
72
+ useMemo(() => {
73
73
  if (!Devise.current().hasGlobalCurrentScope(s.m.scope) && !Devise.current().hasCurrentScope(s.m.scope)) {
74
74
  logger.debug(() => `Devise hasn't got current scope ${s.m.scope} so loading from request`)
75
75
  loadCurrentUserFromRequest()
@@ -1,4 +1,4 @@
1
- import {useCallback, useEffect, useMemo} from "react"
1
+ import {useCallback, useLayoutEffect, useMemo} from "react"
2
2
  import debounceFunction from "debounce"
3
3
  import ModelEvents from "./model-events.mjs"
4
4
  import useShape from "set-state-compare/src/use-shape.js"
@@ -34,7 +34,7 @@ const apiMakerUseDestroyedEvent = (model, onDestroyed, props) => {
34
34
  }
35
35
  }, [])
36
36
 
37
- useEffect(() => {
37
+ useLayoutEffect(() => {
38
38
  let connectDestroyed, onConnectedListener
39
39
 
40
40
  if (model) {
@@ -1,7 +1,7 @@
1
- import {useEffect} from "react"
1
+ import {useLayoutEffect} from "react"
2
2
 
3
3
  const ApiMakerUseEventEmitter = (events, event, onCalled) => {
4
- useEffect(() => {
4
+ useLayoutEffect(() => {
5
5
  if (events) {
6
6
  events.addListener(event, onCalled)
7
7
 
@@ -1,11 +1,11 @@
1
- import {useCallback, useEffect} from "react"
1
+ import {useCallback, useLayoutEffect} from "react"
2
2
 
3
3
  const ApiMakerUseEventListener = (target, event, onCalled) => {
4
4
  const onCalledCallback = useCallback((...args) => {
5
5
  onCalled.apply(null, args)
6
6
  }, [target, event, onCalled])
7
7
 
8
- useEffect(() => {
8
+ useLayoutEffect(() => {
9
9
  if (target) {
10
10
  target.addEventListener(event, onCalledCallback)
11
11
 
package/src/use-model.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import {useCallback, useEffect, useState} from "react"
1
+ import {useCallback, useLayoutEffect, useMemo, useState} from "react"
2
2
  import Devise from "./devise.mjs"
3
3
  import * as inflection from "inflection"
4
4
  import ModelEvents from "./model-events.mjs"
@@ -90,12 +90,12 @@ const useModel = (modelClassArg, argsArg = {}) => {
90
90
  }
91
91
  }, [])
92
92
 
93
- useEffect(
93
+ useMemo(
94
94
  () => { loadModel() },
95
95
  cacheArgs
96
96
  )
97
97
 
98
- useEffect(() => {
98
+ useLayoutEffect(() => {
99
99
  let reloadModelCallback
100
100
 
101
101
  if (args.events) {
@@ -109,7 +109,7 @@ const useModel = (modelClassArg, argsArg = {}) => {
109
109
  }
110
110
  }, [args.events])
111
111
 
112
- useEffect(() => {
112
+ useLayoutEffect(() => {
113
113
  let connectUpdated
114
114
 
115
115
  if (model && args.eventUpdated) {
@@ -129,7 +129,7 @@ const useModel = (modelClassArg, argsArg = {}) => {
129
129
  loadModel()
130
130
  }, [])
131
131
 
132
- useEffect(() => {
132
+ useLayoutEffect(() => {
133
133
  Devise.events().addListener("onDeviseSignIn", onSignedIn)
134
134
  Devise.events().addListener("onDeviseSignOut", onSignedOut)
135
135
 
@@ -147,7 +147,7 @@ const useModel = (modelClassArg, argsArg = {}) => {
147
147
  s.p.onDestroyed(forwardArgs)
148
148
  }, [])
149
149
 
150
- useEffect(() => {
150
+ useLayoutEffect(() => {
151
151
  let connectDestroyed
152
152
 
153
153
  if (model && args.onDestroyed) {
@@ -1,4 +1,4 @@
1
- import {useCallback, useMemo} from "react"
1
+ import {useCallback, useLayoutEffect, useMemo} from "react"
2
2
  import useShape from "set-state-compare/src/use-shape.js"
3
3
 
4
4
  const useResizeObserver = (element, callback) => {
@@ -8,7 +8,7 @@ const useResizeObserver = (element, callback) => {
8
8
  }, [])
9
9
  const observer = useMemo(() => new ResizeObserver(onResize), [])
10
10
 
11
- useEffect(() => {
11
+ useLayoutEffect(() => {
12
12
  if (element) {
13
13
  observer.observe(element)
14
14
  }
@@ -1,4 +1,4 @@
1
- import {useCallback, useEffect, useMemo} from "react"
1
+ import {useCallback, useLayoutEffect, useMemo} from "react"
2
2
  import debounceFunction from "debounce"
3
3
  import ModelEvents from "./model-events.mjs"
4
4
  import useShape from "set-state-compare/src/use-shape.js"
@@ -32,7 +32,7 @@ const apiMakerUseUpdatedEvent = (model, onUpdated, {active = true, debounce, onC
32
32
  }
33
33
  }, [])
34
34
 
35
- useEffect(() => {
35
+ useLayoutEffect(() => {
36
36
  let connectUpdated, onConnectedListener
37
37
 
38
38
  if (model) {