@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
@@ -16,7 +16,7 @@
16
16
  ]
17
17
  },
18
18
  "name": "@kaspernj/api-maker",
19
- "version": "1.0.309",
19
+ "version": "1.0.310",
20
20
  "type": "module",
21
21
  "description": "",
22
22
  "main": "index.js",
@@ -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 Input from "../bootstrap/input"
4
+ import {Pressable, Text, TextInput, View} from "react-native"
5
5
  import Locales from "shared/locales"
6
- import {useCallback, memo} from "react"
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 EditAttribute = ({attribute, model, modelArgs, modelClass}) => {
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 && attribute.content(contentArgs())}
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
- <React.Fragment key={locale}>
30
- <Input
31
- attribute={`${attribute.attribute}${inflection.camelize(locale)}`}
32
- id={`${camelizedLower}_${inflection.underscore(attribute.attribute)}_${locale}`}
33
- label={`${modelClass.humanAttributeName(attribute.attribute)} (${locale})`}
34
- model={model}
35
- name={`${camelizedLower}[${inflection.underscore(attribute.attribute)}_${locale}]`}
36
- />
37
- </React.Fragment>
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
- <Input
41
- attribute={attribute.attribute}
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={`${camelizedLower}[${inflection.underscore(attribute.attribute)}]`}
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 (e) => {
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
- await model.saveRaw(formData)
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
- <div className="super-admin--edit-page">
106
- <form onSubmit={onSubmit}>
107
- {model && attributes?.map((attribute) =>
108
- <EditAttribute attribute={attribute} key={attribute.attribute} model={model} modelArgs={modelArgs} modelClass={modelClass} />
109
- )}
110
- {extraContent && extraContent(modelArgs)}
111
- <button style={{marginTop: "10px"}} type="submit">
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
- </button>
114
- </form>
115
- </div>
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
- }, [modelName, modelId])
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
- {modelClass && pageToShow == "show" &&
79
+ {model && pageToShow == "show" &&
61
80
  <>
62
- <Link className="edit-model-link" to={Params.withParams({model: modelName, model_id: modelId, mode: "edit"})}>
63
- Edit
64
- </Link>
65
- <a className="destroy-model-link" href="#" onClick={onDestroyClicked}>
66
- Delete
67
- </a>
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
- [modelClass, pageToShow]
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 &&