@kaspernj/api-maker 1.0.227 → 1.0.228
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 +1 -1
- package/src/base-error.mjs +3 -5
- package/src/base-model/attribute.mjs +23 -0
- package/src/base-model/reflection.mjs +23 -0
- package/src/base-model.mjs +6 -49
- package/src/model-load-wrapper.jsx +27 -18
- package/src/super-admin/show-page/belongs-to-attribute-row.jsx +25 -0
- package/src/super-admin/show-page/index.jsx +86 -0
- package/src/super-admin/show-page.jsx +0 -60
package/package.json
CHANGED
package/src/base-error.mjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import {dig, digg} from "diggerize"
|
|
2
2
|
import errorMessages from "./error-messages.mjs"
|
|
3
3
|
|
|
4
|
-
class BaseError extends Error {
|
|
4
|
+
export default class BaseError extends Error {
|
|
5
|
+
static apiMakerType = "BaseError"
|
|
6
|
+
|
|
5
7
|
constructor (message, args = {}) {
|
|
6
8
|
let messageToUse = message
|
|
7
9
|
|
|
@@ -34,7 +36,3 @@ class BaseError extends Error {
|
|
|
34
36
|
}
|
|
35
37
|
}
|
|
36
38
|
}
|
|
37
|
-
|
|
38
|
-
BaseError.apiMakerType = "BaseError"
|
|
39
|
-
|
|
40
|
-
export default BaseError
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import {digg} from "diggerize"
|
|
2
|
+
|
|
3
|
+
export default class ApiMakerBaseModelAttribute {
|
|
4
|
+
constructor(attributeData) {
|
|
5
|
+
this.attributeData = attributeData
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
isColumn() {
|
|
9
|
+
return Boolean(digg(this, "attributeData", "column"))
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
isSelectedByDefault() {
|
|
13
|
+
const isSelectedByDefault = digg(this, "attributeData", "selected_by_default")
|
|
14
|
+
|
|
15
|
+
if (isSelectedByDefault || isSelectedByDefault === null) return true
|
|
16
|
+
|
|
17
|
+
return false
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
name() {
|
|
21
|
+
return digg(this, "attributeData", "name")
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import {digg} from "diggerize"
|
|
2
|
+
import inflection from "inflection"
|
|
3
|
+
import modelClassRequire from "../model-class-require.mjs"
|
|
4
|
+
|
|
5
|
+
export default class ApiMakerBaseModelReflection {
|
|
6
|
+
constructor(reflectionData) {
|
|
7
|
+
this.reflectionData = reflectionData
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
macro() {
|
|
11
|
+
return digg(this, "reflectionData", "macro")
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
modelClass() {
|
|
15
|
+
const modelClass = modelClassRequire(inflection.singularize(inflection.camelize(digg(this, "reflectionData", "name"))))
|
|
16
|
+
|
|
17
|
+
return modelClass
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
name() {
|
|
21
|
+
return inflection.camelize(digg(this, "reflectionData", "name"), true)
|
|
22
|
+
}
|
|
23
|
+
}
|
package/src/base-model.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import Attribute from "./base-model/attribute.mjs"
|
|
1
2
|
import AttributeNotLoadedError from "./attribute-not-loaded-error.mjs"
|
|
2
3
|
import Collection from "./collection.mjs"
|
|
3
4
|
import CommandsPool from "./commands-pool.mjs"
|
|
@@ -6,64 +7,24 @@ import CustomError from "./custom-error.mjs"
|
|
|
6
7
|
import {digg} from "diggerize"
|
|
7
8
|
import FormDataObjectizer from "form-data-objectizer"
|
|
8
9
|
import inflection from "inflection"
|
|
9
|
-
import modelClassRequire from "./model-class-require.mjs"
|
|
10
10
|
import ModelName from "./model-name.mjs"
|
|
11
11
|
import NotLoadedError from "./not-loaded-error.mjs"
|
|
12
12
|
import objectToFormData from "object-to-formdata"
|
|
13
|
+
import Reflection from "./base-model/reflection.mjs"
|
|
13
14
|
import Services from "./services.mjs"
|
|
14
15
|
import ValidationError from "./validation-error.mjs"
|
|
15
16
|
import {ValidationErrors} from "./validation-errors.mjs"
|
|
16
17
|
|
|
17
|
-
class
|
|
18
|
-
|
|
19
|
-
this.attributeData = attributeData
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
isColumn() {
|
|
23
|
-
return Boolean(digg(this, "attributeData", "column"))
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
isSelectedByDefault() {
|
|
27
|
-
const isSelectedByDefault = digg(this, "attributeData", "selected_by_default")
|
|
28
|
-
|
|
29
|
-
if (isSelectedByDefault || isSelectedByDefault === null) return true
|
|
30
|
-
|
|
31
|
-
return false
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
name() {
|
|
35
|
-
return digg(this, "attributeData", "name")
|
|
36
|
-
}
|
|
37
|
-
}
|
|
18
|
+
export default class BaseModel {
|
|
19
|
+
static apiMakerType = "BaseModel"
|
|
38
20
|
|
|
39
|
-
class ApiMakerReflection {
|
|
40
|
-
constructor(reflectionData) {
|
|
41
|
-
this.reflectionData = reflectionData
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
macro() {
|
|
45
|
-
return digg(this, "reflectionData", "macro")
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
modelClass() {
|
|
49
|
-
const modelClass = modelClassRequire(inflection.singularize(inflection.camelize(digg(this, "reflectionData", "name"))))
|
|
50
|
-
|
|
51
|
-
return modelClass
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
name() {
|
|
55
|
-
return inflection.camelize(digg(this, "reflectionData", "name"), true)
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
class BaseModel {
|
|
60
21
|
static attributes() {
|
|
61
22
|
const attributes = digg(this.modelClassData(), "attributes")
|
|
62
23
|
const result = []
|
|
63
24
|
|
|
64
25
|
for (const attributeKey in attributes) {
|
|
65
26
|
const attributeData = attributes[attributeKey]
|
|
66
|
-
const attribute = new
|
|
27
|
+
const attribute = new Attribute(attributeData)
|
|
67
28
|
|
|
68
29
|
result.push(attribute)
|
|
69
30
|
}
|
|
@@ -128,7 +89,7 @@ class BaseModel {
|
|
|
128
89
|
const reflections = []
|
|
129
90
|
|
|
130
91
|
for (const relationshipData of relationships) {
|
|
131
|
-
const reflection = new
|
|
92
|
+
const reflection = new Reflection(relationshipData)
|
|
132
93
|
|
|
133
94
|
reflections.push(reflection)
|
|
134
95
|
}
|
|
@@ -910,7 +871,3 @@ class BaseModel {
|
|
|
910
871
|
}
|
|
911
872
|
}
|
|
912
873
|
}
|
|
913
|
-
|
|
914
|
-
BaseModel.apiMakerType = "BaseModel"
|
|
915
|
-
|
|
916
|
-
export default BaseModel
|
|
@@ -5,13 +5,14 @@ import PropTypes from "prop-types"
|
|
|
5
5
|
import React from "react"
|
|
6
6
|
import withQueryParams from "on-location-changed/src/with-query-params"
|
|
7
7
|
|
|
8
|
-
export default (WrappedComponent,
|
|
8
|
+
export default (WrappedComponent, modelClassArg, argsArg = {}) => {
|
|
9
9
|
class ModelLoadWrapper extends React.PureComponent {
|
|
10
10
|
static propTypes = {
|
|
11
11
|
queryParams: PropTypes.object
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
modelClass = this.resolveModelClass(
|
|
14
|
+
modelClass = this.resolveModelClass(modelClassArg)
|
|
15
|
+
args = this.resolveArgs()
|
|
15
16
|
camelizedLower = this.modelClass.modelName().camelizedLower()
|
|
16
17
|
paramsVariableName = `${this.modelClass.modelName().paramKey()}_id`
|
|
17
18
|
|
|
@@ -21,6 +22,16 @@ export default (WrappedComponent, mdelClassArg, args = {}) => {
|
|
|
21
22
|
notFound: undefined
|
|
22
23
|
}
|
|
23
24
|
|
|
25
|
+
resolveArgs() {
|
|
26
|
+
if (typeof argsArg == "function") {
|
|
27
|
+
return argsArg({
|
|
28
|
+
modelClass: this.modelClass
|
|
29
|
+
})
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return argsArg
|
|
33
|
+
}
|
|
34
|
+
|
|
24
35
|
resolveModelClass(modelClassArg) {
|
|
25
36
|
if (typeof modelClassArg == "object") {
|
|
26
37
|
const {queryParams} = digs(this.props, "queryParams")
|
|
@@ -46,16 +57,16 @@ export default (WrappedComponent, mdelClassArg, args = {}) => {
|
|
|
46
57
|
}
|
|
47
58
|
|
|
48
59
|
loadModel = async () => {
|
|
49
|
-
if (args.newIfNoId && !this.getModelId()) {
|
|
60
|
+
if (this.args.newIfNoId && !this.getModelId()) {
|
|
50
61
|
return await this.loadNewModel()
|
|
51
|
-
} else if (!args.optional || this.getModelId()) {
|
|
62
|
+
} else if (!this.args.optional || this.getModelId()) {
|
|
52
63
|
return await this.loadExistingModel()
|
|
53
64
|
}
|
|
54
65
|
}
|
|
55
66
|
|
|
56
67
|
getModelId() {
|
|
57
|
-
if (args.loadByQueryParam)
|
|
58
|
-
return args.loadByQueryParam({props: this.props})
|
|
68
|
+
if (this.args.loadByQueryParam)
|
|
69
|
+
return this.args.loadByQueryParam({props: this.props})
|
|
59
70
|
|
|
60
71
|
return this.props.match.params[this.paramsVariableName] || this.props.match.params.id
|
|
61
72
|
}
|
|
@@ -65,9 +76,9 @@ export default (WrappedComponent, mdelClassArg, args = {}) => {
|
|
|
65
76
|
const ModelClass = digg(this, "modelClass")
|
|
66
77
|
const query = await ModelClass.ransack({id_eq: modelId})
|
|
67
78
|
|
|
68
|
-
if (args.abilities) query.abilities(args.abilities)
|
|
69
|
-
if (args.preload) query.preload(args.preload)
|
|
70
|
-
if (args.select) query.select(args.select)
|
|
79
|
+
if (this.args.abilities) query.abilities(this.args.abilities)
|
|
80
|
+
if (this.args.preload) query.preload(this.args.preload)
|
|
81
|
+
if (this.args.select) query.select(this.args.select)
|
|
71
82
|
|
|
72
83
|
const model = await query.first()
|
|
73
84
|
|
|
@@ -85,11 +96,11 @@ export default (WrappedComponent, mdelClassArg, args = {}) => {
|
|
|
85
96
|
|
|
86
97
|
let defaults = {}
|
|
87
98
|
|
|
88
|
-
if (args.newIfNoId?.defaults) {
|
|
89
|
-
defaults = await args.newIfNoId.defaults()
|
|
99
|
+
if (this.args.newIfNoId?.defaults) {
|
|
100
|
+
defaults = await this.args.newIfNoId.defaults()
|
|
90
101
|
}
|
|
91
102
|
|
|
92
|
-
const modelData = Object.assign(defaults, args.newAttributes, modelDataFromParams)
|
|
103
|
+
const modelData = Object.assign(defaults, this.args.newAttributes, modelDataFromParams)
|
|
93
104
|
const model = new ModelClass({
|
|
94
105
|
isNewRecord: true,
|
|
95
106
|
data: {a: modelData}
|
|
@@ -109,10 +120,10 @@ export default (WrappedComponent, mdelClassArg, args = {}) => {
|
|
|
109
120
|
|
|
110
121
|
return (
|
|
111
122
|
<>
|
|
112
|
-
{args.events &&
|
|
113
|
-
<EventEmitterListener event="reloadModel" events={args.events} onCalled={reloadModel} />
|
|
123
|
+
{this.args.events &&
|
|
124
|
+
<EventEmitterListener event="reloadModel" events={this.args.events} onCalled={reloadModel} />
|
|
114
125
|
}
|
|
115
|
-
{model && args.eventUpdated &&
|
|
126
|
+
{model && this.args.eventUpdated &&
|
|
116
127
|
<EventUpdated model={model} onUpdated={onUpdated} />
|
|
117
128
|
}
|
|
118
129
|
<WrappedComponent {...wrappedComponentProps} {...this.props} />
|
|
@@ -124,7 +135,5 @@ export default (WrappedComponent, mdelClassArg, args = {}) => {
|
|
|
124
135
|
onUpdated = this.loadExistingModel
|
|
125
136
|
}
|
|
126
137
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
return ModelLoadWrapper
|
|
138
|
+
return withQueryParams(ModelLoadWrapper)
|
|
130
139
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import AttributeRow from "../../bootstrap/attribute-row"
|
|
2
|
+
import {digs} from "diggerize"
|
|
3
|
+
import inflection from "inflection"
|
|
4
|
+
import Link from "../../link"
|
|
5
|
+
import Params from "../../params"
|
|
6
|
+
import React from "react"
|
|
7
|
+
|
|
8
|
+
export default class ApiMakerSuperAdminShowPageBelongsToAttributeRow extends React.PureComponent {
|
|
9
|
+
render() {
|
|
10
|
+
const {model, modelClass, reflection} = digs(this.props, "model", "modelClass", "reflection")
|
|
11
|
+
const reflectionMethodName = inflection.camelize(reflection.name(), true)
|
|
12
|
+
const subModel = model[reflectionMethodName]()
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<AttributeRow label={modelClass.humanAttributeName(inflection.camelize(reflection.name(), true))}>
|
|
16
|
+
{subModel &&
|
|
17
|
+
<Link to={Params.withParams({model: subModel.modelClassData().name, model_id: subModel.primaryKey()})}>
|
|
18
|
+
{subModel && "name" in subModel && subModel.name()}
|
|
19
|
+
{subModel && !("name" in subModel) && subModel?.id()}
|
|
20
|
+
</Link>
|
|
21
|
+
}
|
|
22
|
+
</AttributeRow>
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import AttributeRows from "../../bootstrap/attribute-rows"
|
|
2
|
+
import BelongsToAttributeRow from "./belongs-to-attribute-row"
|
|
3
|
+
import ConfigReader from "../config-reader"
|
|
4
|
+
import {digg, digs} from "diggerize"
|
|
5
|
+
import modelLoadWrapper from "../../model-load-wrapper"
|
|
6
|
+
import PropTypes from "prop-types"
|
|
7
|
+
import React from "react"
|
|
8
|
+
import ShowNav from "../show-nav"
|
|
9
|
+
|
|
10
|
+
class ApiMakerSuperAdminShowPage extends React.PureComponent {
|
|
11
|
+
static propTypes = {
|
|
12
|
+
modelClass: PropTypes.func.isRequired,
|
|
13
|
+
queryParams: PropTypes.object.isRequired
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
render() {
|
|
17
|
+
const {modelClass, queryParams} = digs(this.props, "modelClass", "queryParams")
|
|
18
|
+
const attributes = this.attributes()
|
|
19
|
+
const model = this.model()
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<div className="super-admin--show-page">
|
|
23
|
+
{model &&
|
|
24
|
+
<ShowNav model={model} modelClass={modelClass} queryParams={queryParams} />
|
|
25
|
+
}
|
|
26
|
+
{attributes && model &&
|
|
27
|
+
<AttributeRows attributes={attributes} model={model} />
|
|
28
|
+
}
|
|
29
|
+
{model && modelClass.reflections().filter((reflection) => reflection.macro() == "belongs_to").map((reflection) =>
|
|
30
|
+
<BelongsToAttributeRow key={reflection.name()} model={model} modelClass={modelClass} reflection={reflection} />
|
|
31
|
+
)}
|
|
32
|
+
</div>
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
attributes() {
|
|
37
|
+
const {modelClass} = digs(this.props, "modelClass")
|
|
38
|
+
const configReader = ConfigReader.forModel(modelClass)
|
|
39
|
+
|
|
40
|
+
return configReader.attributesToShow()
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
model() {
|
|
44
|
+
const {modelClass} = digs(this.props, "modelClass")
|
|
45
|
+
const camelizedLower = digg(modelClass.modelClassData(), "camelizedLower")
|
|
46
|
+
|
|
47
|
+
return digg(this, "props", camelizedLower)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const modelClassResolver = {callback: ({queryParams}) => {
|
|
52
|
+
const modelClassName = digg(queryParams, "model")
|
|
53
|
+
const modelClass = digg(require("../../models.mjs.erb"), modelClassName)
|
|
54
|
+
|
|
55
|
+
return modelClass
|
|
56
|
+
}}
|
|
57
|
+
|
|
58
|
+
export default modelLoadWrapper(
|
|
59
|
+
ApiMakerSuperAdminShowPage,
|
|
60
|
+
modelClassResolver,
|
|
61
|
+
({modelClass}) => {
|
|
62
|
+
const preload = []
|
|
63
|
+
const select = {}
|
|
64
|
+
|
|
65
|
+
for (const reflection of modelClass.reflections()) {
|
|
66
|
+
if (reflection.macro() != "belongs_to") continue
|
|
67
|
+
|
|
68
|
+
const reflectionModelClass = reflection.modelClass()
|
|
69
|
+
const reflectionModelClassName = reflectionModelClass.modelClassData().name
|
|
70
|
+
const reflectionModelClassAttributes = reflectionModelClass.attributes()
|
|
71
|
+
const nameAttribute = reflectionModelClassAttributes.find((attribute) => attribute.name() == "name")
|
|
72
|
+
|
|
73
|
+
preload.push(reflection.name())
|
|
74
|
+
|
|
75
|
+
if (!(reflectionModelClassName in select)) select[reflectionModelClassName] = []
|
|
76
|
+
if (!select[reflectionModelClassName].includes("id")) select[reflectionModelClassName].push("id")
|
|
77
|
+
if (nameAttribute && !select[reflectionModelClassName].includes("name")) select[reflectionModelClassName].push("name")
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
loadByQueryParam: ({props}) => props.queryParams.model_id,
|
|
82
|
+
preload,
|
|
83
|
+
select
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
)
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import AttributeRows from "../bootstrap/attribute-rows"
|
|
2
|
-
import ConfigReader from "./config-reader"
|
|
3
|
-
import {digg, digs} from "diggerize"
|
|
4
|
-
import modelLoadWrapper from "../model-load-wrapper"
|
|
5
|
-
import PropTypes from "prop-types"
|
|
6
|
-
import React from "react"
|
|
7
|
-
import ShowNav from "./show-nav"
|
|
8
|
-
|
|
9
|
-
class ApiMakerSuperAdminShowPage extends React.PureComponent {
|
|
10
|
-
static propTypes = {
|
|
11
|
-
modelClass: PropTypes.func.isRequired,
|
|
12
|
-
queryParams: PropTypes.object.isRequired
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
render() {
|
|
16
|
-
const {modelClass, queryParams} = digs(this.props, "modelClass", "queryParams")
|
|
17
|
-
const attributes = this.attributes()
|
|
18
|
-
const model = this.model()
|
|
19
|
-
|
|
20
|
-
return (
|
|
21
|
-
<div className="super-admin--show-page">
|
|
22
|
-
{model &&
|
|
23
|
-
<ShowNav model={model} modelClass={modelClass} queryParams={queryParams} />
|
|
24
|
-
}
|
|
25
|
-
{attributes && model &&
|
|
26
|
-
<AttributeRows attributes={attributes} model={model} />
|
|
27
|
-
}
|
|
28
|
-
</div>
|
|
29
|
-
)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
attributes() {
|
|
33
|
-
const {modelClass} = digs(this.props, "modelClass")
|
|
34
|
-
const configReader = ConfigReader.forModel(modelClass)
|
|
35
|
-
|
|
36
|
-
return configReader.attributesToShow()
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
model() {
|
|
40
|
-
const {modelClass} = digs(this.props, "modelClass")
|
|
41
|
-
const camelizedLower = digg(modelClass.modelClassData(), "camelizedLower")
|
|
42
|
-
|
|
43
|
-
return digg(this, "props", camelizedLower)
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const modelClassResolver = {callback: ({queryParams}) => {
|
|
48
|
-
const modelClassName = digg(queryParams, "model")
|
|
49
|
-
const modelClass = digg(require("../models.mjs.erb"), modelClassName)
|
|
50
|
-
|
|
51
|
-
return modelClass
|
|
52
|
-
}}
|
|
53
|
-
|
|
54
|
-
export default modelLoadWrapper(
|
|
55
|
-
ApiMakerSuperAdminShowPage,
|
|
56
|
-
modelClassResolver,
|
|
57
|
-
{
|
|
58
|
-
loadByQueryParam: ({props}) => props.queryParams.model_id
|
|
59
|
-
}
|
|
60
|
-
)
|