@kaspernj/api-maker 1.0.309 → 1.0.310
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,48 +1,103 @@
|
|
|
1
1
|
import ConfigReader from "./config-reader"
|
|
2
2
|
import {digg} from "diggerize"
|
|
3
3
|
import * as inflection from "inflection"
|
|
4
|
-
import
|
|
4
|
+
import {Pressable, Text, TextInput, View} from "react-native"
|
|
5
5
|
import Locales from "shared/locales"
|
|
6
|
-
import {useCallback,
|
|
6
|
+
import {memo, useCallback, useEffect, 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"
|
|
10
10
|
|
|
11
|
-
const
|
|
11
|
+
const EditAttributeInput = ({attributeName, id, inputs, label, model, name}) => {
|
|
12
|
+
const defaultValue = useCallback(() => model[attributeName]() || "")
|
|
13
|
+
const [value, setValue] = useState(() => defaultValue())
|
|
14
|
+
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
inputs[name] = value
|
|
17
|
+
}, [])
|
|
18
|
+
|
|
19
|
+
const onChangeText = useCallback((newValue) => {
|
|
20
|
+
inputs[name] = newValue
|
|
21
|
+
setValue(newValue)
|
|
22
|
+
}, [])
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<View style={{marginBottom: 12}}>
|
|
26
|
+
<Text>{label}</Text>
|
|
27
|
+
<View>
|
|
28
|
+
<TextInput
|
|
29
|
+
dataSet={{
|
|
30
|
+
attribute: attributeName,
|
|
31
|
+
id,
|
|
32
|
+
name
|
|
33
|
+
}}
|
|
34
|
+
onChangeText={onChangeText}
|
|
35
|
+
style={{paddingTop: 9, paddingRight: 13, paddingBottom: 9, paddingLeft: 13, borderRadius: 5, backgroundColor: "#fff", border: "1px solid #cecece"}}
|
|
36
|
+
value={value}
|
|
37
|
+
/>
|
|
38
|
+
</View>
|
|
39
|
+
</View>
|
|
40
|
+
)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const EditAttributeContent = ({attribute, id, inputs, model, name}) => {
|
|
44
|
+
const defaultValue = useCallback(() => model[attribute.attribute]() || "")
|
|
45
|
+
const [value, setValue] = useState(() => defaultValue())
|
|
46
|
+
const onChangeValue = useCallback((newValue) => {
|
|
47
|
+
inputs[name] = newValue
|
|
48
|
+
setValue(newValue)
|
|
49
|
+
})
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
inputs[name] = value
|
|
52
|
+
}, [])
|
|
53
|
+
|
|
54
|
+
const contentArgs = () => ({
|
|
55
|
+
inputProps: {
|
|
56
|
+
attribute: attribute.attribute,
|
|
57
|
+
defaultValue: defaultValue(),
|
|
58
|
+
id,
|
|
59
|
+
model
|
|
60
|
+
},
|
|
61
|
+
onChangeValue
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
return attribute.content(contentArgs())
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const EditAttribute = ({attribute, inputs, model, modelClass}) => {
|
|
12
68
|
const availableLocales = Locales.availableLocales()
|
|
13
69
|
const camelizedLower = digg(modelClass.modelClassData(), "camelizedLower")
|
|
14
|
-
const contentArgs = () => {
|
|
15
|
-
const contentArgsResult = {
|
|
16
|
-
inputProps: {
|
|
17
|
-
attribute: attribute.attribute,
|
|
18
|
-
model
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
return contentArgsResult
|
|
23
|
-
}
|
|
24
70
|
|
|
25
71
|
return (
|
|
26
72
|
<>
|
|
27
|
-
{attribute.content &&
|
|
73
|
+
{attribute.content &&
|
|
74
|
+
<EditAttributeContent
|
|
75
|
+
attribute={attribute}
|
|
76
|
+
id={`${camelizedLower}_${inflection.underscore(attribute.attribute)}`}
|
|
77
|
+
inputs={inputs}
|
|
78
|
+
model={model}
|
|
79
|
+
name={inflection.underscore(attribute.attribute)}
|
|
80
|
+
/>
|
|
81
|
+
}
|
|
28
82
|
{!attribute.content && attribute.translated && availableLocales.map((locale) =>
|
|
29
|
-
<
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
83
|
+
<EditAttributeInput
|
|
84
|
+
attributeName={`${attribute.attribute}${inflection.camelize(locale)}`}
|
|
85
|
+
id={`${camelizedLower}_${inflection.underscore(attribute.attribute)}_${locale}`}
|
|
86
|
+
inputs={inputs}
|
|
87
|
+
label={`${modelClass.humanAttributeName(attribute.attribute)} (${locale})`}
|
|
88
|
+
model={model}
|
|
89
|
+
name={`${inflection.underscore(attribute.attribute)}_${locale}`}
|
|
90
|
+
key={locale}
|
|
91
|
+
/>
|
|
38
92
|
)}
|
|
39
93
|
{!attribute.content && !attribute.translated &&
|
|
40
|
-
<
|
|
41
|
-
|
|
94
|
+
<EditAttributeInput
|
|
95
|
+
attributeName={attribute.attribute}
|
|
42
96
|
id={`${camelizedLower}_${inflection.underscore(attribute.attribute)}`}
|
|
97
|
+
inputs={inputs}
|
|
43
98
|
label={modelClass.humanAttributeName(attribute.attribute)}
|
|
44
99
|
model={model}
|
|
45
|
-
name={
|
|
100
|
+
name={inflection.underscore(attribute.attribute)}
|
|
46
101
|
/>
|
|
47
102
|
}
|
|
48
103
|
</>
|
|
@@ -54,6 +109,7 @@ const EditPage = ({modelClass}) => {
|
|
|
54
109
|
const currentUser = useCurrentUser()
|
|
55
110
|
const queryParams = useQueryParams()
|
|
56
111
|
const configReader = ConfigReader.forModel(modelClass)
|
|
112
|
+
const inputs = useMemo(() => ({}))
|
|
57
113
|
const modelClassName = modelClass.modelClassData().name
|
|
58
114
|
const modelIdVarName = `${inflection.camelize(modelClass.modelClassData().name, true)}Id`
|
|
59
115
|
const modelVarName = inflection.camelize(modelClass.modelClassData().name, true)
|
|
@@ -87,14 +143,11 @@ const EditPage = ({modelClass}) => {
|
|
|
87
143
|
|
|
88
144
|
modelArgs[modelIdVarName] = modelId
|
|
89
145
|
|
|
90
|
-
const onSubmit = useCallback(async (
|
|
91
|
-
e.preventDefault()
|
|
92
|
-
|
|
93
|
-
const form = digg(e, "target")
|
|
94
|
-
const formData = new FormData(form)
|
|
95
|
-
|
|
146
|
+
const onSubmit = useCallback(async () => {
|
|
96
147
|
try {
|
|
97
|
-
|
|
148
|
+
model.assignAttributes(inputs)
|
|
149
|
+
|
|
150
|
+
await model.save(inputs)
|
|
98
151
|
Params.changeParams({mode: undefined, model_id: model.id()})
|
|
99
152
|
} catch (error) {
|
|
100
153
|
FlashMessage.errorResponse(error)
|
|
@@ -102,17 +155,29 @@ const EditPage = ({modelClass}) => {
|
|
|
102
155
|
}, [model])
|
|
103
156
|
|
|
104
157
|
return (
|
|
105
|
-
<
|
|
106
|
-
|
|
107
|
-
{
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
158
|
+
<View dataSet={{class: "super-admin--edit-page"}}>
|
|
159
|
+
{model && attributes?.map((attribute) =>
|
|
160
|
+
<EditAttribute attribute={attribute} inputs={inputs} key={attribute.attribute} model={model} modelClass={modelClass} />
|
|
161
|
+
)}
|
|
162
|
+
{extraContent && extraContent(modelArgs)}
|
|
163
|
+
<Pressable
|
|
164
|
+
dataSet={{class: "submit-button"}}
|
|
165
|
+
onPress={onSubmit}
|
|
166
|
+
style={{
|
|
167
|
+
paddingTop: 18,
|
|
168
|
+
paddingRight: 24,
|
|
169
|
+
paddingBottom: 18,
|
|
170
|
+
paddingLeft: 24,
|
|
171
|
+
borderRadius: 10,
|
|
172
|
+
backgroundColor: "#4c93ff",
|
|
173
|
+
marginTop: "10px"
|
|
174
|
+
}}
|
|
175
|
+
>
|
|
176
|
+
<Text style={{color: "#fff"}}>
|
|
112
177
|
Submit
|
|
113
|
-
</
|
|
114
|
-
</
|
|
115
|
-
</
|
|
178
|
+
</Text>
|
|
179
|
+
</Pressable>
|
|
180
|
+
</View>
|
|
116
181
|
)
|
|
117
182
|
}
|
|
118
183
|
|
|
@@ -4,7 +4,7 @@ import Layout from "./layout"
|
|
|
4
4
|
import Link from "../link"
|
|
5
5
|
import {memo, useMemo} from "react"
|
|
6
6
|
import * as modelsModule from "@kaspernj/api-maker/src/models.mjs.erb"
|
|
7
|
-
import {useCallback} from "react"
|
|
7
|
+
import {useCallback, useEffect, useState} from "react"
|
|
8
8
|
import ShowPage from "./show-page"
|
|
9
9
|
import ShowReflectionPage from "./show-reflection-page"
|
|
10
10
|
import useQueryParams from "on-location-changed/src/use-query-params"
|
|
@@ -17,6 +17,27 @@ const ApiMakerSuperAdmin = () => {
|
|
|
17
17
|
|
|
18
18
|
const modelId = queryParams.model_id
|
|
19
19
|
const modelName = modelClass?.modelClassData()?.name
|
|
20
|
+
const [model, setModel] = useState()
|
|
21
|
+
|
|
22
|
+
const loadModel = useCallback(async () => {
|
|
23
|
+
if (modelId && modelClass) {
|
|
24
|
+
const abilities = {}
|
|
25
|
+
const abilitiesForModel = ["destroy", "edit"]
|
|
26
|
+
|
|
27
|
+
abilities[modelName] = abilitiesForModel
|
|
28
|
+
|
|
29
|
+
const model = await modelClass
|
|
30
|
+
.ransack({id_eq: modelId})
|
|
31
|
+
.abilities(abilities)
|
|
32
|
+
.first()
|
|
33
|
+
|
|
34
|
+
setModel(model)
|
|
35
|
+
} else {
|
|
36
|
+
setModel(undefined)
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
useEffect(() => { loadModel() }, [modelId])
|
|
20
41
|
|
|
21
42
|
if (queryParams.model && queryParams.model_id && queryParams.model_reflection) {
|
|
22
43
|
pageToShow = "show_reflection"
|
|
@@ -40,15 +61,13 @@ const ApiMakerSuperAdmin = () => {
|
|
|
40
61
|
}
|
|
41
62
|
|
|
42
63
|
try {
|
|
43
|
-
const model = await modelClass.find(modelId)
|
|
44
|
-
|
|
45
64
|
await model.destroy()
|
|
46
65
|
|
|
47
66
|
Params.changeParams({mode: undefined, model_id: undefined})
|
|
48
67
|
} catch (error) {
|
|
49
68
|
FlashMessage.errorResponse(error)
|
|
50
69
|
}
|
|
51
|
-
}, [
|
|
70
|
+
}, [model])
|
|
52
71
|
|
|
53
72
|
const actions = useMemo(
|
|
54
73
|
() => <>
|
|
@@ -57,18 +76,22 @@ const ApiMakerSuperAdmin = () => {
|
|
|
57
76
|
Create new
|
|
58
77
|
</Link>
|
|
59
78
|
}
|
|
60
|
-
{
|
|
79
|
+
{model && pageToShow == "show" &&
|
|
61
80
|
<>
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
81
|
+
{model.can("edit") &&
|
|
82
|
+
<Link className="edit-model-link" to={Params.withParams({model: modelName, model_id: modelId, mode: "edit"})}>
|
|
83
|
+
Edit
|
|
84
|
+
</Link>
|
|
85
|
+
}
|
|
86
|
+
{model.can("destroy") &&
|
|
87
|
+
<a className="destroy-model-link" href="#" onClick={onDestroyClicked}>
|
|
88
|
+
Delete
|
|
89
|
+
</a>
|
|
90
|
+
}
|
|
68
91
|
</>
|
|
69
92
|
}
|
|
70
93
|
</>,
|
|
71
|
-
[
|
|
94
|
+
[model, pageToShow]
|
|
72
95
|
)
|
|
73
96
|
|
|
74
97
|
return (
|
|
@@ -18,8 +18,6 @@ const AttributePresenter = ({attribute, model, modelArgs}) => {
|
|
|
18
18
|
attributeRowProps.attribute = attribute
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
console.log({attributeRowProps})
|
|
22
|
-
|
|
23
21
|
return (
|
|
24
22
|
<AttributeRow model={model} {...attributeRowProps} />
|
|
25
23
|
)
|
|
@@ -73,8 +71,6 @@ const ApiMakerSuperAdminShowPage = ({modelClass}) => {
|
|
|
73
71
|
|
|
74
72
|
modelArgs[inflection.camelize(modelClass.modelClassData().name, true)] = model
|
|
75
73
|
|
|
76
|
-
console.log({attributes})
|
|
77
|
-
|
|
78
74
|
return (
|
|
79
75
|
<div className="super-admin--show-page">
|
|
80
76
|
{model &&
|