@kaspernj/api-maker 1.0.388 → 1.0.390
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 +2 -2
- package/src/form.jsx +68 -0
- package/src/inputs/attachment.jsx +9 -4
- package/src/inputs/checkbox.jsx +13 -4
- package/src/inputs/checkboxes.jsx +5 -3
- package/src/inputs/input.jsx +8 -3
- package/src/inputs/select.jsx +21 -5
- package/src/super-admin/config-reader.jsx +5 -5
- package/src/super-admin/edit-page/edit-attribute-content.jsx +38 -16
- package/src/super-admin/edit-page/edit-attribute-input.jsx +11 -0
- package/src/super-admin/edit-page.jsx +35 -24
- package/src/super-admin/index-page.jsx +3 -2
- package/src/super-admin/layout/header/index.jsx +79 -11
- package/src/super-admin/layout/header/style.scss +3 -54
- package/src/super-admin/layout/index.jsx +32 -25
- package/src/super-admin/layout/menu/index.jsx +14 -6
- package/src/super-admin/layout/menu/style.scss +1 -1
- package/src/super-admin/layout/no-access.jsx +10 -5
- package/src/super-admin/layout/style.scss +2 -2
- package/src/super-admin/model-class-table.jsx +2 -0
- package/src/super-admin/show-nav.jsx +10 -7
- package/src/super-admin/show-page/index.jsx +6 -3
- package/src/super-admin/show-reflection-page.jsx +5 -3
- package/src/table/table.jsx +4 -2
- package/src/table/with-breakpoint.jsx +0 -9
- /package/src/{table/use-breakpoint.mjs → use-breakpoint.mjs} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kaspernj/api-maker",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.390",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "",
|
|
6
6
|
"main": "index.js",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"on-location-changed": ">= 1.0.13",
|
|
36
36
|
"qs": ">= 6.9.3",
|
|
37
37
|
"replaceall": ">= 0.1.6",
|
|
38
|
-
"set-state-compare": "^1.0.
|
|
38
|
+
"set-state-compare": "^1.0.46",
|
|
39
39
|
"spark-md5": "^3.0.2",
|
|
40
40
|
"stacktrace-parser": "^0.1.10",
|
|
41
41
|
"strftime": ">= 0.10.0",
|
package/src/form.jsx
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import {createContext, memo, useContext, useMemo} from "react"
|
|
2
|
+
import BaseComponent from "./base-component"
|
|
3
|
+
import FormDataObjectizer from "form-data-objectizer"
|
|
4
|
+
import {Platform} from "react-native"
|
|
5
|
+
import {shapeComponent} from "set-state-compare/src/shape-component.js"
|
|
6
|
+
|
|
7
|
+
const FormContext = createContext(null)
|
|
8
|
+
|
|
9
|
+
class FormClass {
|
|
10
|
+
constructor() {
|
|
11
|
+
this.inputs = {}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
asObject() {
|
|
15
|
+
const result = {}
|
|
16
|
+
const formDataObjectizer = new FormDataObjectizer()
|
|
17
|
+
|
|
18
|
+
for(const key in this.inputs) {
|
|
19
|
+
const value = this.inputs[key]
|
|
20
|
+
|
|
21
|
+
formDataObjectizer.treatInitial(key, value, result)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return result
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
setValue(name, value) {
|
|
28
|
+
console.log("Form", {name, value})
|
|
29
|
+
|
|
30
|
+
this.inputs[name] = value
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
setValueWithHidden(name, value) {
|
|
34
|
+
this.setValue(name, value)
|
|
35
|
+
|
|
36
|
+
if (Platform.OS == "web") {
|
|
37
|
+
return <input name={name} type="hidden" value={value !== null && value !== undefined ? value : ""} />
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const Form = memo(shapeComponent(class Form extends BaseComponent {
|
|
43
|
+
render() {
|
|
44
|
+
const {children, setForm, ...restProps} = this.props
|
|
45
|
+
const form = useMemo(() => new FormClass(), [])
|
|
46
|
+
|
|
47
|
+
useMemo(() => {
|
|
48
|
+
if (setForm) {
|
|
49
|
+
setForm(form)
|
|
50
|
+
}
|
|
51
|
+
}, [setForm])
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<FormContext.Provider value={form}>
|
|
55
|
+
{Platform.OS == "web" &&
|
|
56
|
+
<form {...restProps}>
|
|
57
|
+
{children}
|
|
58
|
+
</form>
|
|
59
|
+
}
|
|
60
|
+
{Platform.OS != "web" && this.props.children}
|
|
61
|
+
</FormContext.Provider>
|
|
62
|
+
)
|
|
63
|
+
}
|
|
64
|
+
}))
|
|
65
|
+
|
|
66
|
+
const useForm = () => useContext(FormContext)
|
|
67
|
+
|
|
68
|
+
export {Form, FormContext, useForm}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import BaseComponent from "../base-component"
|
|
1
2
|
import {Input as ApiMakerInput} from "@kaspernj/api-maker/src/inputs/input"
|
|
2
3
|
import {Checkbox} from "./checkbox"
|
|
4
|
+
import {memo} from "react"
|
|
5
|
+
import {shapeComponent} from "set-state-compare/src/shape-component.js"
|
|
3
6
|
|
|
4
|
-
export default class ApiMakerInputsAttachment extends BaseComponent {
|
|
7
|
+
export default memo(shapeComponent(class ApiMakerInputsAttachment extends BaseComponent {
|
|
5
8
|
static propTypes = {
|
|
6
9
|
className: PropTypes.string,
|
|
7
10
|
model: PropTypes.object.isRequired,
|
|
@@ -9,8 +12,10 @@ export default class ApiMakerInputsAttachment extends BaseComponent {
|
|
|
9
12
|
purgeName: PropTypes.string
|
|
10
13
|
}
|
|
11
14
|
|
|
12
|
-
|
|
13
|
-
|
|
15
|
+
setup() {
|
|
16
|
+
this.useStates({
|
|
17
|
+
purgeChecked: false
|
|
18
|
+
})
|
|
14
19
|
}
|
|
15
20
|
|
|
16
21
|
render() {
|
|
@@ -91,4 +96,4 @@ export default class ApiMakerInputsAttachment extends BaseComponent {
|
|
|
91
96
|
|
|
92
97
|
if (this.props.onPurgeChanged) this.props.onPurgeChanged(e)
|
|
93
98
|
}
|
|
94
|
-
}
|
|
99
|
+
}))
|
package/src/inputs/checkbox.jsx
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import AutoSubmit from "./auto-submit.mjs"
|
|
2
|
+
import BaseComponent from "../base-component"
|
|
2
3
|
import {digg, digs} from "diggerize"
|
|
3
4
|
import EventUpdated from "../event-updated"
|
|
4
5
|
import inputWrapper from "./input-wrapper"
|
|
5
6
|
import PropTypes from "prop-types"
|
|
6
|
-
import
|
|
7
|
+
import {memo} from "react"
|
|
8
|
+
import {shapeComponent} from "set-state-compare/src/shape-component.js"
|
|
9
|
+
import {useForm} from "../form"
|
|
7
10
|
|
|
8
|
-
class ApiMakerInputsCheckbox extends
|
|
11
|
+
const ApiMakerInputsCheckbox = memo(shapeComponent(class ApiMakerInputsCheckbox extends BaseComponent {
|
|
9
12
|
static defaultProps = {
|
|
10
13
|
autoRefresh: false,
|
|
11
14
|
autoSubmit: false,
|
|
@@ -28,6 +31,10 @@ class ApiMakerInputsCheckbox extends React.PureComponent {
|
|
|
28
31
|
zeroInput: PropTypes.bool
|
|
29
32
|
}
|
|
30
33
|
|
|
34
|
+
setup() {
|
|
35
|
+
this.form = useForm()
|
|
36
|
+
}
|
|
37
|
+
|
|
31
38
|
render () {
|
|
32
39
|
const {
|
|
33
40
|
attribute,
|
|
@@ -69,9 +76,11 @@ class ApiMakerInputsCheckbox extends React.PureComponent {
|
|
|
69
76
|
}
|
|
70
77
|
|
|
71
78
|
onChanged = (...args) => {
|
|
72
|
-
const {
|
|
79
|
+
const {form} = this.tt
|
|
80
|
+
const {attribute, autoSubmit, model, name, onChange} = this.props
|
|
73
81
|
|
|
74
82
|
if (attribute && autoSubmit && model) new AutoSubmit({component: this}).autoSubmit()
|
|
83
|
+
if (form && name) form.setValue(name, args[0].target.checked)
|
|
75
84
|
if (onChange) onChange(...args)
|
|
76
85
|
}
|
|
77
86
|
|
|
@@ -92,7 +101,7 @@ class ApiMakerInputsCheckbox extends React.PureComponent {
|
|
|
92
101
|
inputRef.current.checked = newValue
|
|
93
102
|
}
|
|
94
103
|
}
|
|
95
|
-
}
|
|
104
|
+
}))
|
|
96
105
|
|
|
97
106
|
export {ApiMakerInputsCheckbox as Checkbox}
|
|
98
107
|
export default inputWrapper(ApiMakerInputsCheckbox, {type: "checkbox"})
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import BaseComponent from "../base-component"
|
|
1
2
|
import classNames from "classnames"
|
|
2
3
|
import {digs} from "diggerize"
|
|
3
4
|
import inputWrapper from "./input-wrapper"
|
|
@@ -5,9 +6,10 @@ import * as inflection from "inflection"
|
|
|
5
6
|
import InvalidFeedback from "../bootstrap/invalid-feedback"
|
|
6
7
|
import PropTypes from "prop-types"
|
|
7
8
|
import propTypesExact from "prop-types-exact"
|
|
8
|
-
import
|
|
9
|
+
import {memo} from "react"
|
|
10
|
+
import {shapeComponent} from "set-state-compare/src/shape-component.js"
|
|
9
11
|
|
|
10
|
-
class ApiMakerInputsCheckboxes extends
|
|
12
|
+
const ApiMakerInputsCheckboxes = memo(shapeComponent(class ApiMakerInputsCheckboxes extends BaseComponent {
|
|
11
13
|
static propTypes = propTypesExact({
|
|
12
14
|
attribute: PropTypes.string,
|
|
13
15
|
defaultValue: PropTypes.array,
|
|
@@ -108,6 +110,6 @@ class ApiMakerInputsCheckboxes extends React.PureComponent {
|
|
|
108
110
|
</div>
|
|
109
111
|
)
|
|
110
112
|
}
|
|
111
|
-
}
|
|
113
|
+
}))
|
|
112
114
|
|
|
113
115
|
export default inputWrapper(ApiMakerInputsCheckboxes)
|
package/src/inputs/input.jsx
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import AutoSubmit from "./auto-submit.mjs"
|
|
2
|
+
import BaseComponent from "../base-component"
|
|
2
3
|
import {dig, digg, digs} from "diggerize"
|
|
3
4
|
import EventUpdated from "../event-updated"
|
|
4
5
|
import inputWrapper from "./input-wrapper"
|
|
@@ -6,10 +7,11 @@ import Money from "./money"
|
|
|
6
7
|
import PropTypes from "prop-types"
|
|
7
8
|
import {memo, useRef} from "react"
|
|
8
9
|
import replaceall from "replaceall"
|
|
9
|
-
import {shapeComponent
|
|
10
|
+
import {shapeComponent} from "set-state-compare/src/shape-component.js"
|
|
10
11
|
import strftime from "strftime"
|
|
12
|
+
import {useForm} from "../form"
|
|
11
13
|
|
|
12
|
-
const ApiMakerInputsInput = memo(shapeComponent(class ApiMakerInputsInput extends
|
|
14
|
+
const ApiMakerInputsInput = memo(shapeComponent(class ApiMakerInputsInput extends BaseComponent {
|
|
13
15
|
static defaultProps = {
|
|
14
16
|
autoRefresh: false,
|
|
15
17
|
autoSubmit: false,
|
|
@@ -32,6 +34,7 @@ const ApiMakerInputsInput = memo(shapeComponent(class ApiMakerInputsInput extend
|
|
|
32
34
|
}
|
|
33
35
|
|
|
34
36
|
setup() {
|
|
37
|
+
this.form = useForm()
|
|
35
38
|
this.visibleInputRef = useRef()
|
|
36
39
|
|
|
37
40
|
this.useStates({
|
|
@@ -204,13 +207,15 @@ const ApiMakerInputsInput = memo(shapeComponent(class ApiMakerInputsInput extend
|
|
|
204
207
|
}
|
|
205
208
|
|
|
206
209
|
onInputChanged = (e) => {
|
|
207
|
-
const {
|
|
210
|
+
const {form} = this.tt
|
|
211
|
+
const {attribute, autoSubmit, inputProps, model, name, onChange} = this.props
|
|
208
212
|
const {localizedNumber} = digs(this.props, "localizedNumber")
|
|
209
213
|
|
|
210
214
|
if (localizedNumber) this.inputReference().current.value = this.actualValue(digg(e, "target"))
|
|
211
215
|
|
|
212
216
|
if (attribute && autoSubmit && model) this.delayAutoSubmit()
|
|
213
217
|
if (digg(inputProps, "type") == "file") this.setState({blankInputName: this.getBlankInputName()})
|
|
218
|
+
if (form && name) form.setValue(name, e.target.value)
|
|
214
219
|
if (onChange) onChange(e)
|
|
215
220
|
}
|
|
216
221
|
|
package/src/inputs/select.jsx
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import
|
|
1
|
+
import BaseComponent from "../base-component"
|
|
2
2
|
import inputWrapper from "./input-wrapper"
|
|
3
3
|
import PropTypes from "prop-types"
|
|
4
|
-
import
|
|
4
|
+
import {memo} from "react"
|
|
5
|
+
import {shapeComponent} from "set-state-compare/src/shape-component.js"
|
|
6
|
+
import {useForm} from "../form"
|
|
5
7
|
|
|
6
|
-
class ApiMakerInputsSelect extends
|
|
8
|
+
const ApiMakerInputsSelect = memo(shapeComponent(class ApiMakerInputsSelect extends BaseComponent {
|
|
7
9
|
static propTypes = {
|
|
8
10
|
attribute: PropTypes.string,
|
|
9
11
|
children: PropTypes.node,
|
|
@@ -13,10 +15,15 @@ class ApiMakerInputsSelect extends React.PureComponent {
|
|
|
13
15
|
inputProps: PropTypes.object.isRequired,
|
|
14
16
|
model: PropTypes.object,
|
|
15
17
|
name: PropTypes.string,
|
|
18
|
+
onChange: PropTypes.func,
|
|
16
19
|
options: PropTypes.array,
|
|
17
20
|
wrapperOpts: PropTypes.object.isRequired
|
|
18
21
|
}
|
|
19
22
|
|
|
23
|
+
setup() {
|
|
24
|
+
this.form = useForm()
|
|
25
|
+
}
|
|
26
|
+
|
|
20
27
|
render () {
|
|
21
28
|
const {
|
|
22
29
|
attribute,
|
|
@@ -28,13 +35,14 @@ class ApiMakerInputsSelect extends React.PureComponent {
|
|
|
28
35
|
inputRef,
|
|
29
36
|
model,
|
|
30
37
|
name,
|
|
38
|
+
onChange,
|
|
31
39
|
options,
|
|
32
40
|
wrapperOpts,
|
|
33
41
|
...restProps
|
|
34
42
|
} = this.props
|
|
35
43
|
|
|
36
44
|
return (
|
|
37
|
-
<select {...inputProps} {...restProps}>
|
|
45
|
+
<select onChange={this.tt.onChange} {...inputProps} {...restProps}>
|
|
38
46
|
{this.includeBlank() &&
|
|
39
47
|
<option data-include-blank="true">
|
|
40
48
|
{typeof includeBlank != "boolean" ? includeBlank : null}
|
|
@@ -50,6 +58,14 @@ class ApiMakerInputsSelect extends React.PureComponent {
|
|
|
50
58
|
)
|
|
51
59
|
}
|
|
52
60
|
|
|
61
|
+
onChange = (e) => {
|
|
62
|
+
const {form} = this.tt
|
|
63
|
+
const {name, onChange} = this.props
|
|
64
|
+
|
|
65
|
+
if (form && name) form.setValue(name, e.target.value)
|
|
66
|
+
if (onChange) onChange(e)
|
|
67
|
+
}
|
|
68
|
+
|
|
53
69
|
optionKey (option) {
|
|
54
70
|
if (Array.isArray(option)) {
|
|
55
71
|
return `select-option-${option[1]}`
|
|
@@ -81,7 +97,7 @@ class ApiMakerInputsSelect extends React.PureComponent {
|
|
|
81
97
|
return false
|
|
82
98
|
}
|
|
83
99
|
}
|
|
84
|
-
}
|
|
100
|
+
}))
|
|
85
101
|
|
|
86
102
|
export {ApiMakerInputsSelect as Select}
|
|
87
103
|
export default inputWrapper(ApiMakerInputsSelect)
|
|
@@ -49,12 +49,12 @@ export default class ApiMakerSuperAdminConfigReader {
|
|
|
49
49
|
const {modelConfig} = digs(this, "modelConfig")
|
|
50
50
|
|
|
51
51
|
if (modelConfig?.table?.columns) {
|
|
52
|
-
return
|
|
52
|
+
return {
|
|
53
|
+
columns: modelConfig.table.columns()
|
|
54
|
+
}
|
|
55
|
+
} else {
|
|
56
|
+
return this.defaultTableColumns()
|
|
53
57
|
}
|
|
54
|
-
|
|
55
|
-
const {columns} = this.defaultTableColumns()
|
|
56
|
-
|
|
57
|
-
return columns
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
defaultTableColumns() {
|
|
@@ -1,35 +1,57 @@
|
|
|
1
1
|
import BaseComponent from "../../base-component"
|
|
2
|
+
import {FormContext} from "../../form"
|
|
2
3
|
import {memo} from "react"
|
|
3
4
|
import {shapeComponent} from "set-state-compare/src/shape-component.js"
|
|
4
5
|
|
|
5
6
|
export default memo(shapeComponent(class EditAttributeContent extends BaseComponent {
|
|
7
|
+
setup() {
|
|
8
|
+
const {inputs, name} = this.p
|
|
9
|
+
|
|
10
|
+
this.form = useContext(FormContext)
|
|
11
|
+
this.useStates({
|
|
12
|
+
value: () => this.defaultValue()
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
useMemo(() => {
|
|
16
|
+
inputs[name] = this.s.value
|
|
17
|
+
|
|
18
|
+
if (this.form) {
|
|
19
|
+
this.form.setValue(name, this.s.value)
|
|
20
|
+
}
|
|
21
|
+
}, [])
|
|
22
|
+
}
|
|
23
|
+
|
|
6
24
|
render() {
|
|
7
|
-
const {attribute, id,
|
|
25
|
+
const {attribute, id, model} = this.props
|
|
8
26
|
|
|
9
27
|
if (!(attribute.attribute in model)) {
|
|
10
28
|
throw new Error(`${attribute.attribute} isn't set on the resource ${model.modelClassData().name}`)
|
|
11
29
|
}
|
|
12
30
|
|
|
13
|
-
const
|
|
14
|
-
const [value, setValue] = useState(() => defaultValue())
|
|
15
|
-
const onChangeValue = useCallback((newValue) => {
|
|
16
|
-
inputs[name] = newValue
|
|
17
|
-
setValue(newValue)
|
|
18
|
-
})
|
|
19
|
-
useMemo(() => {
|
|
20
|
-
inputs[name] = value
|
|
21
|
-
}, [])
|
|
22
|
-
|
|
23
|
-
const contentArgs = () => ({
|
|
31
|
+
const contentArgs = useMemo(() => ({
|
|
24
32
|
inputProps: {
|
|
25
33
|
attribute: attribute.attribute,
|
|
26
|
-
defaultValue: defaultValue(),
|
|
34
|
+
defaultValue: this.defaultValue(),
|
|
27
35
|
id,
|
|
28
36
|
model
|
|
29
37
|
},
|
|
30
|
-
onChangeValue
|
|
31
|
-
})
|
|
38
|
+
onChangeValue: this.tt.onChangeValue
|
|
39
|
+
}), [attribute.attribute, id, model])
|
|
40
|
+
|
|
41
|
+
return attribute.content(contentArgs)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
defaultValue = () => this.p.model[this.p.attribute.attribute]() || ""
|
|
45
|
+
|
|
46
|
+
onChangeValue = (newValue) => {
|
|
47
|
+
const {inputs, name} = this.p
|
|
48
|
+
|
|
49
|
+
inputs[name] = newValue
|
|
50
|
+
|
|
51
|
+
if (this.form) {
|
|
52
|
+
this.form.setValue(name, newValue)
|
|
53
|
+
}
|
|
32
54
|
|
|
33
|
-
|
|
55
|
+
this.setState({value: newValue})
|
|
34
56
|
}
|
|
35
57
|
}))
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import BaseComponent from "../../base-component"
|
|
2
|
+
import {useForm} from "../../form"
|
|
2
3
|
import PropTypes from "prop-types"
|
|
3
4
|
import propTypesExact from "prop-types-exact"
|
|
4
5
|
import {shapeComponent} from "set-state-compare/src/shape-component.js"
|
|
@@ -14,12 +15,17 @@ export default memo(shapeComponent(class EditAttributeInput extends BaseComponen
|
|
|
14
15
|
setup() {
|
|
15
16
|
const {inputs, name} = this.p
|
|
16
17
|
|
|
18
|
+
this.form = useForm()
|
|
17
19
|
this.useStates({
|
|
18
20
|
value: this.defaultValue()
|
|
19
21
|
})
|
|
20
22
|
|
|
21
23
|
useMemo(() => {
|
|
22
24
|
inputs[name] = this.s.value
|
|
25
|
+
|
|
26
|
+
if (this.form) {
|
|
27
|
+
this.form.setValue(name, this.s.value)
|
|
28
|
+
}
|
|
23
29
|
}, [])
|
|
24
30
|
}
|
|
25
31
|
|
|
@@ -56,6 +62,11 @@ export default memo(shapeComponent(class EditAttributeInput extends BaseComponen
|
|
|
56
62
|
const {inputs, name} = this.p
|
|
57
63
|
|
|
58
64
|
inputs[name] = newValue
|
|
65
|
+
|
|
66
|
+
if (this.form) {
|
|
67
|
+
this.form.setValue(name, newValue)
|
|
68
|
+
}
|
|
69
|
+
|
|
59
70
|
this.setState({value: newValue})
|
|
60
71
|
}
|
|
61
72
|
}))
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import {Pressable, Text, View} from "react-native"
|
|
1
2
|
import BaseComponent from "../base-component"
|
|
2
3
|
import ConfigReader from "./config-reader.jsx"
|
|
3
4
|
import {digg} from "diggerize"
|
|
4
5
|
import EditAttribute from "./edit-page/edit-attribute"
|
|
6
|
+
import {Form} from "../form"
|
|
5
7
|
import * as inflection from "inflection"
|
|
6
|
-
import {Pressable, Text, View} from "react-native"
|
|
7
8
|
import Locales from "shared/locales"
|
|
8
9
|
import {memo} from "react"
|
|
9
10
|
import PropTypes from "prop-types"
|
|
@@ -50,7 +51,8 @@ export default memo(shapeComponent(class ApiMakerSuperAdminEditPage extends Base
|
|
|
50
51
|
const useModelResult = useModel(modelClass, {
|
|
51
52
|
cacheArgs: [currentUser?.id()],
|
|
52
53
|
loadByQueryParam: (props) => props.queryParams.model_id,
|
|
53
|
-
newIfNoId: true,
|
|
54
|
+
newIfNoId: this.configReader.modelConfig?.edit?.newIfNoId || true,
|
|
55
|
+
preload: this.configReader.modelConfig?.edit?.preload,
|
|
54
56
|
select: selectedAttributes
|
|
55
57
|
})
|
|
56
58
|
|
|
@@ -61,6 +63,7 @@ export default memo(shapeComponent(class ApiMakerSuperAdminEditPage extends Base
|
|
|
61
63
|
this.modelId = queryParams.model_id
|
|
62
64
|
this.modelArgs = {}
|
|
63
65
|
this.modelArgs[modelIdVarName] = this.modelId
|
|
66
|
+
this.useStates({form: null})
|
|
64
67
|
}
|
|
65
68
|
|
|
66
69
|
render() {
|
|
@@ -70,27 +73,29 @@ export default memo(shapeComponent(class ApiMakerSuperAdminEditPage extends Base
|
|
|
70
73
|
|
|
71
74
|
return (
|
|
72
75
|
<View dataSet={{class: "super-admin--edit-page"}}>
|
|
73
|
-
{
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
76
|
+
<Form setForm={this.setStates.form}>
|
|
77
|
+
{model && attributes?.map((attribute) =>
|
|
78
|
+
<EditAttribute attribute={attribute} inputs={this.inputs} key={attribute.attribute} model={model} modelClass={modelClass} />
|
|
79
|
+
)}
|
|
80
|
+
{extraContent && extraContent(modelArgs)}
|
|
81
|
+
<Pressable
|
|
82
|
+
dataSet={{class: "submit-button"}}
|
|
83
|
+
onPress={this.tt.onSubmit}
|
|
84
|
+
style={{
|
|
85
|
+
paddingTop: 18,
|
|
86
|
+
paddingRight: 24,
|
|
87
|
+
paddingBottom: 18,
|
|
88
|
+
paddingLeft: 24,
|
|
89
|
+
borderRadius: 10,
|
|
90
|
+
backgroundColor: "#4c93ff",
|
|
91
|
+
marginTop: 10
|
|
92
|
+
}}
|
|
93
|
+
>
|
|
94
|
+
<Text style={{color: "#fff"}}>
|
|
95
|
+
Submit
|
|
96
|
+
</Text>
|
|
97
|
+
</Pressable>
|
|
98
|
+
</Form>
|
|
94
99
|
</View>
|
|
95
100
|
)
|
|
96
101
|
}
|
|
@@ -98,8 +103,14 @@ export default memo(shapeComponent(class ApiMakerSuperAdminEditPage extends Base
|
|
|
98
103
|
onSubmit = async () => {
|
|
99
104
|
try {
|
|
100
105
|
const {inputs, model} = this.tt
|
|
106
|
+
const {form} = this.s
|
|
107
|
+
|
|
108
|
+
const formObject = form.asObject()
|
|
109
|
+
const allInputs = Object.assign({}, inputs, formObject)
|
|
110
|
+
|
|
111
|
+
console.log({allInputs})
|
|
101
112
|
|
|
102
|
-
model.assignAttributes(
|
|
113
|
+
model.assignAttributes(allInputs)
|
|
103
114
|
await model.save(this.inputs)
|
|
104
115
|
Params.changeParams({mode: undefined, model_id: model.id()})
|
|
105
116
|
} catch (error) {
|
|
@@ -3,6 +3,7 @@ import {memo} from "react"
|
|
|
3
3
|
import ModelClassTable from "./model-class-table"
|
|
4
4
|
import PropTypes from "prop-types"
|
|
5
5
|
import {shapeComponent} from "set-state-compare/src/shape-component.js"
|
|
6
|
+
import {View} from "react-native"
|
|
6
7
|
|
|
7
8
|
export default memo(shapeComponent(class ApiMakerSuperAdminIndexPage extends BaseComponent {
|
|
8
9
|
static propTypes = {
|
|
@@ -13,9 +14,9 @@ export default memo(shapeComponent(class ApiMakerSuperAdminIndexPage extends Bas
|
|
|
13
14
|
const {modelClass} = this.props
|
|
14
15
|
|
|
15
16
|
return (
|
|
16
|
-
<
|
|
17
|
+
<View dataSet={{component: "super-admin--index-page"}}>
|
|
17
18
|
<ModelClassTable modelClass={modelClass} />
|
|
18
|
-
</
|
|
19
|
+
</View>
|
|
19
20
|
)
|
|
20
21
|
}
|
|
21
22
|
}))
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import "./style"
|
|
2
2
|
import BaseComponent from "../../../base-component"
|
|
3
|
-
import EventListener from "../../../event-listener"
|
|
4
3
|
import {memo, useRef} from "react"
|
|
5
4
|
import PropTypes from "prop-types"
|
|
6
5
|
import PropTypesExact from "prop-types-exact"
|
|
7
6
|
import {shapeComponent} from "set-state-compare/src/shape-component.js"
|
|
7
|
+
import {Text, View} from "react-native"
|
|
8
|
+
import useBreakpoint from "../../../use-breakpoint"
|
|
9
|
+
import useEventListener from "../../../use-event-listener"
|
|
8
10
|
|
|
9
11
|
export default memo(shapeComponent(class ApiMakerSuperAdminLayoutHeader extends BaseComponent {
|
|
10
12
|
static propTypes = PropTypesExact({
|
|
@@ -14,27 +16,93 @@ export default memo(shapeComponent(class ApiMakerSuperAdminLayoutHeader extends
|
|
|
14
16
|
})
|
|
15
17
|
|
|
16
18
|
setup() {
|
|
19
|
+
const {breakpoint} = useBreakpoint()
|
|
20
|
+
|
|
17
21
|
this.headerActionsRef = useRef()
|
|
22
|
+
this.setInstance({breakpoint})
|
|
18
23
|
this.useStates({
|
|
19
24
|
headerActionsActive: false
|
|
20
25
|
})
|
|
26
|
+
|
|
27
|
+
useEventListener(window, "mouseup", this.tt.onWindowMouseUp)
|
|
21
28
|
}
|
|
22
29
|
|
|
23
30
|
render() {
|
|
31
|
+
const {breakpoint} = this.tt
|
|
24
32
|
const {actions, onTriggerMenu, title} = this.props
|
|
25
33
|
|
|
34
|
+
const headerStyle = {
|
|
35
|
+
display: "flex",
|
|
36
|
+
flexDirection: "row",
|
|
37
|
+
alignItems: "center",
|
|
38
|
+
zIndex: 9,
|
|
39
|
+
height: 100,
|
|
40
|
+
paddingRight: 30,
|
|
41
|
+
paddingLeft: 30,
|
|
42
|
+
backgroundColor: "#fff"
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const headerActionsContainerStyle = {}
|
|
46
|
+
const headerActionsStyle = {}
|
|
47
|
+
|
|
48
|
+
if (breakpoint == "xs" || breakpoint == "sm") {
|
|
49
|
+
headerStyle.position = "absolute"
|
|
50
|
+
headerStyle.width = "100%"
|
|
51
|
+
|
|
52
|
+
Object.assign(headerActionsContainerStyle, {
|
|
53
|
+
position: "fixed",
|
|
54
|
+
top: 0,
|
|
55
|
+
left: 0,
|
|
56
|
+
|
|
57
|
+
display: "flex",
|
|
58
|
+
width: "100vw",
|
|
59
|
+
height: "100vh",
|
|
60
|
+
alignItems: "center",
|
|
61
|
+
justifyContent: "center",
|
|
62
|
+
|
|
63
|
+
background: "rgba(#000, .8)"
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
if (!this.s.headerActionsActive) {
|
|
67
|
+
headerActionsContainerStyle.display = "none"
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
Object.assign(headerActionsStyle, {
|
|
71
|
+
minWidth: "80vw",
|
|
72
|
+
maxWidth: "100vw",
|
|
73
|
+
backgroundColor: "#fff"
|
|
74
|
+
})
|
|
75
|
+
} else if (breakpoint == "md") {
|
|
76
|
+
headerStyle.position = "fixed"
|
|
77
|
+
headerStyle.left = 250
|
|
78
|
+
headerStyle.width = "calc(100% - 250px)"
|
|
79
|
+
} else if (breakpoint == "lg" || breakpoint == "xl" || breakpoint == "xxl") {
|
|
80
|
+
headerStyle.position = "fixed"
|
|
81
|
+
headerStyle.left = 290
|
|
82
|
+
headerStyle.width = "calc(100% - 290px)"
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (breakpoint == "md" || breakpoint == "lg" || breakpoint == "xl" || breakpoint == "xxl") {
|
|
86
|
+
headerActionsContainerStyle.marginLeft = "auto"
|
|
87
|
+
}
|
|
88
|
+
|
|
26
89
|
return (
|
|
27
|
-
<
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
90
|
+
<View dataSet={{component: "super-admin--layout--header"}} style={headerStyle}>
|
|
91
|
+
<View dataSet={{class: "header-title-container"}}>
|
|
92
|
+
<Text style={{color: "#282a33", fontSize: 22}}>
|
|
93
|
+
{title}
|
|
94
|
+
</Text>
|
|
95
|
+
</View>
|
|
32
96
|
{actions &&
|
|
33
|
-
<
|
|
34
|
-
<
|
|
97
|
+
<View dataSet={{active: this.s.headerActionsActive, class: "header-actions-container"}} style={headerActionsContainerStyle}>
|
|
98
|
+
<View
|
|
99
|
+
dataSet={{class: "header-actions"}}
|
|
100
|
+
ref={this.tt.headerActionsRef}
|
|
101
|
+
style={headerActionsStyle}
|
|
102
|
+
>
|
|
35
103
|
{actions}
|
|
36
|
-
</
|
|
37
|
-
</
|
|
104
|
+
</View>
|
|
105
|
+
</View>
|
|
38
106
|
}
|
|
39
107
|
<div className="burger-menu-container">
|
|
40
108
|
{actions &&
|
|
@@ -46,7 +114,7 @@ export default memo(shapeComponent(class ApiMakerSuperAdminLayoutHeader extends
|
|
|
46
114
|
<i className="fa fa-bars" />
|
|
47
115
|
</a>
|
|
48
116
|
</div>
|
|
49
|
-
</
|
|
117
|
+
</View>
|
|
50
118
|
)
|
|
51
119
|
}
|
|
52
120
|
|
|
@@ -1,42 +1,8 @@
|
|
|
1
1
|
@import "@kaspernj/api-maker/src/super-admin/stylesheets/variables";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
top: 0;
|
|
5
|
-
display: flex;
|
|
6
|
-
height: 100px;
|
|
7
|
-
align-items: center;
|
|
8
|
-
padding-right: 30px;
|
|
9
|
-
padding-left: 30px;
|
|
10
|
-
background: #fff;
|
|
11
|
-
color: #282a33;
|
|
12
|
-
|
|
3
|
+
[data-component="super-admin--layout--header"] {
|
|
13
4
|
@media (max-width: $sm-to) {
|
|
14
|
-
|
|
15
|
-
width: 100%;
|
|
16
|
-
|
|
17
|
-
.header-actions-container {
|
|
18
|
-
position: fixed;
|
|
19
|
-
top: 0;
|
|
20
|
-
left: 0;
|
|
21
|
-
|
|
22
|
-
display: flex;
|
|
23
|
-
width: 100vw;
|
|
24
|
-
height: 100vh;
|
|
25
|
-
align-items: center;
|
|
26
|
-
justify-content: center;
|
|
27
|
-
|
|
28
|
-
background: rgba(#000, .8);
|
|
29
|
-
|
|
30
|
-
&[data-active="false"] {
|
|
31
|
-
display: none;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
.header-actions {
|
|
36
|
-
min-width: 80vw;
|
|
37
|
-
max-width: 100vw;
|
|
38
|
-
background: #fff;
|
|
39
|
-
|
|
5
|
+
[data-class="header-actions"] {
|
|
40
6
|
.action-button {
|
|
41
7
|
display: block;
|
|
42
8
|
padding: 11px;
|
|
@@ -63,15 +29,7 @@
|
|
|
63
29
|
}
|
|
64
30
|
|
|
65
31
|
@media (min-width: $md-from) {
|
|
66
|
-
|
|
67
|
-
left: 250px;
|
|
68
|
-
width: calc(100% - 250px);
|
|
69
|
-
|
|
70
|
-
.header-actions-container {
|
|
71
|
-
margin-left: auto;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
.header-actions {
|
|
32
|
+
[data-class="header-actions"] {
|
|
75
33
|
.action-button {
|
|
76
34
|
display: inline-block;
|
|
77
35
|
padding: 7px 10px;
|
|
@@ -89,11 +47,6 @@
|
|
|
89
47
|
}
|
|
90
48
|
}
|
|
91
49
|
|
|
92
|
-
@media (min-width: $lg-from) {
|
|
93
|
-
left: 290px;
|
|
94
|
-
width: calc(100% - 290px);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
50
|
.burger-menu-container {
|
|
98
51
|
@media (max-width: $sm-to) {
|
|
99
52
|
margin-left: auto;
|
|
@@ -117,8 +70,4 @@
|
|
|
117
70
|
color: #1b1c1e;
|
|
118
71
|
}
|
|
119
72
|
}
|
|
120
|
-
|
|
121
|
-
.header-title-container {
|
|
122
|
-
font-size: 22px;
|
|
123
|
-
}
|
|
124
73
|
}
|
|
@@ -7,10 +7,11 @@ import Header from "./header"
|
|
|
7
7
|
import Menu from "./menu"
|
|
8
8
|
import PropTypes from "prop-types"
|
|
9
9
|
import PropTypesExact from "prop-types-exact"
|
|
10
|
-
import {memo,
|
|
10
|
+
import {memo, useMemo} from "react"
|
|
11
11
|
import {shapeComponent} from "set-state-compare/src/shape-component.js"
|
|
12
12
|
import useCurrentUser from "../../use-current-user"
|
|
13
|
-
import
|
|
13
|
+
import useI18n from "i18n-on-steroids/src/use-i18n.mjs"
|
|
14
|
+
import {View} from "react-native"
|
|
14
15
|
|
|
15
16
|
const NoAccess = React.lazy(() => import("./no-access"))
|
|
16
17
|
|
|
@@ -27,7 +28,21 @@ export default memo(shapeComponent(class ApiMakerSuperAdminLayout extends BaseCo
|
|
|
27
28
|
headerTitle: PropTypes.string
|
|
28
29
|
})
|
|
29
30
|
|
|
31
|
+
setup() {
|
|
32
|
+
const currentUser = useCurrentUser()
|
|
33
|
+
const {locale, t} = useI18n({namespace: "js.api_maker.super_admin.layout"})
|
|
34
|
+
|
|
35
|
+
this.useStates({menuTriggered: false})
|
|
36
|
+
this.setInstance({currentUser, t})
|
|
37
|
+
|
|
38
|
+
useMemo(() => {
|
|
39
|
+
CommandsPool.current().globalRequestData.layout = "admin"
|
|
40
|
+
CommandsPool.current().globalRequestData.locale = locale
|
|
41
|
+
}, [I18n.locale])
|
|
42
|
+
}
|
|
43
|
+
|
|
30
44
|
render() {
|
|
45
|
+
const {currentUser, t} = this.tt
|
|
31
46
|
const {
|
|
32
47
|
actions,
|
|
33
48
|
active,
|
|
@@ -39,14 +54,6 @@ export default memo(shapeComponent(class ApiMakerSuperAdminLayout extends BaseCo
|
|
|
39
54
|
menu,
|
|
40
55
|
...restProps
|
|
41
56
|
} = this.props
|
|
42
|
-
const s = useShape()
|
|
43
|
-
const currentUser = useCurrentUser()
|
|
44
|
-
|
|
45
|
-
useMemo(() => {
|
|
46
|
-
CommandsPool.current().globalRequestData.layout = "admin"
|
|
47
|
-
CommandsPool.current().globalRequestData.locale = I18n.locale
|
|
48
|
-
}, [I18n.locale])
|
|
49
|
-
|
|
50
57
|
const headTitle = headTitle || headerTitle
|
|
51
58
|
|
|
52
59
|
if (headTitle) {
|
|
@@ -55,38 +62,32 @@ export default memo(shapeComponent(class ApiMakerSuperAdminLayout extends BaseCo
|
|
|
55
62
|
document.title = "Wooftech"
|
|
56
63
|
}
|
|
57
64
|
|
|
58
|
-
const setMenuTriggered = s.useState("menuTriggered", false)
|
|
59
65
|
const noAccess = !currentUser
|
|
60
|
-
const onRequestMenuClose = useCallback(() => setMenuTriggered(false), [])
|
|
61
|
-
const onTriggerMenu = useCallback((e) => {
|
|
62
|
-
e.preventDefault()
|
|
63
|
-
setMenuTriggered(!s.state.menuTriggered)
|
|
64
|
-
}, [])
|
|
65
66
|
|
|
66
67
|
return (
|
|
67
|
-
<
|
|
68
|
+
<View dataSet={{component: "super-admin--layout", class: className, menuTriggered: this.s.menuTriggered}} {...restProps}>
|
|
68
69
|
<Menu
|
|
69
70
|
active={active}
|
|
70
71
|
noAccess={noAccess}
|
|
71
|
-
onRequestMenuClose={onRequestMenuClose}
|
|
72
|
-
triggered={s.
|
|
72
|
+
onRequestMenuClose={this.tt.onRequestMenuClose}
|
|
73
|
+
triggered={this.s.menuTriggered}
|
|
73
74
|
/>
|
|
74
|
-
<Header actions={actions} onTriggerMenu={onTriggerMenu} title={headerTitle} />
|
|
75
|
-
<
|
|
75
|
+
<Header actions={actions} onTriggerMenu={this.tt.onTriggerMenu} title={headerTitle} />
|
|
76
|
+
<View dataSet={{class: "app-layout-content-container"}}>
|
|
76
77
|
{noAccess &&
|
|
77
78
|
<>
|
|
78
79
|
<NoAccess />
|
|
79
80
|
{currentUser &&
|
|
80
81
|
<>
|
|
81
82
|
<div className="mb-4">
|
|
82
|
-
{
|
|
83
|
+
{t(".try_signing_out_and_in_with_a_different_user", {defaultValue: "Try signing in with a different user."})}
|
|
83
84
|
</div>
|
|
84
85
|
</>
|
|
85
86
|
}
|
|
86
87
|
{!currentUser &&
|
|
87
88
|
<>
|
|
88
89
|
<div className="mb-4">
|
|
89
|
-
{
|
|
90
|
+
{t(".try_signing_in", {defaultValue: "Try signing in."})}
|
|
90
91
|
</div>
|
|
91
92
|
{config.signInContent()}
|
|
92
93
|
</>
|
|
@@ -94,8 +95,14 @@ export default memo(shapeComponent(class ApiMakerSuperAdminLayout extends BaseCo
|
|
|
94
95
|
</>
|
|
95
96
|
}
|
|
96
97
|
{!noAccess && children}
|
|
97
|
-
</
|
|
98
|
-
</
|
|
98
|
+
</View>
|
|
99
|
+
</View>
|
|
99
100
|
)
|
|
100
101
|
}
|
|
102
|
+
|
|
103
|
+
onRequestMenuClose = () => this.setState({menuTriggered: false})
|
|
104
|
+
onTriggerMenu = (e) => {
|
|
105
|
+
e.preventDefault()
|
|
106
|
+
setMenuTriggered(!this.s.menuTriggered)
|
|
107
|
+
}
|
|
101
108
|
}))
|
|
@@ -8,6 +8,8 @@ import PropTypes from "prop-types"
|
|
|
8
8
|
import PropTypesExact from "prop-types-exact"
|
|
9
9
|
import {shapeComponent} from "set-state-compare/src/shape-component.js"
|
|
10
10
|
import useCurrentUser from "../../../use-current-user"
|
|
11
|
+
import useI18n from "i18n-on-steroids/src/use-i18n.mjs"
|
|
12
|
+
import {View} from "react-native"
|
|
11
13
|
|
|
12
14
|
export default memo(shapeComponent(class ComponentsAdminLayoutMenu extends BaseComponent {
|
|
13
15
|
static propTypes = PropTypesExact({
|
|
@@ -17,13 +19,19 @@ export default memo(shapeComponent(class ComponentsAdminLayoutMenu extends BaseC
|
|
|
17
19
|
triggered: PropTypes.bool.isRequired
|
|
18
20
|
})
|
|
19
21
|
|
|
22
|
+
setup() {
|
|
23
|
+
const {t} = useI18n({namespace: "js.api_maker.super_admin.layout.menu"})
|
|
24
|
+
const currentUser = useCurrentUser()
|
|
25
|
+
|
|
26
|
+
this.setInstance({currentUser, t})
|
|
27
|
+
}
|
|
28
|
+
|
|
20
29
|
render() {
|
|
30
|
+
const {currentUser, t} = this.tt
|
|
21
31
|
const {active, noAccess, triggered} = this.props
|
|
22
|
-
const currentUser = useCurrentUser()
|
|
23
|
-
const rootRef = useRef()
|
|
24
32
|
|
|
25
33
|
return (
|
|
26
|
-
<
|
|
34
|
+
<View dataSet={{component: "super-admin--layout--menu", triggered}}>
|
|
27
35
|
<div className="menu-logo">
|
|
28
36
|
<Link className="menu-logo-link" to={Params.withParams({})}>
|
|
29
37
|
Admin
|
|
@@ -52,12 +60,12 @@ export default memo(shapeComponent(class ComponentsAdminLayoutMenu extends BaseC
|
|
|
52
60
|
active
|
|
53
61
|
className="sign-out-menu-item"
|
|
54
62
|
icon="sign-out-alt"
|
|
55
|
-
label={
|
|
63
|
+
label={t(".sign_out", {defaultValue: "Sign out"})}
|
|
56
64
|
onClick={this.tt.onSignOutClicked}
|
|
57
65
|
/>
|
|
58
66
|
}
|
|
59
67
|
</div>
|
|
60
|
-
</
|
|
68
|
+
</View>
|
|
61
69
|
)
|
|
62
70
|
}
|
|
63
71
|
|
|
@@ -66,7 +74,7 @@ export default memo(shapeComponent(class ComponentsAdminLayoutMenu extends BaseC
|
|
|
66
74
|
|
|
67
75
|
try {
|
|
68
76
|
await Devise.signOut()
|
|
69
|
-
FlashMessage.success(
|
|
77
|
+
FlashMessage.success(this.t(".you_have_been_signed_out", {defaultValue: "You have been signed out"}))
|
|
70
78
|
} catch (error) {
|
|
71
79
|
FlashMessage.errorResponse(error)
|
|
72
80
|
}
|
|
@@ -2,18 +2,23 @@ import BaseComponent from "../../base-component"
|
|
|
2
2
|
import {memo} from "react"
|
|
3
3
|
import {shapeComponent} from "set-state-compare/src/shape-component.js"
|
|
4
4
|
import useCurrentUser from "../../use-current-user"
|
|
5
|
+
import useI18n from "i18n-on-steroids/src/use-i18n.mjs"
|
|
6
|
+
import {View} from "react-native"
|
|
5
7
|
|
|
6
8
|
export default memo(shapeComponent(class ComponentsAdminLayoutNoAccess extends BaseComponent {
|
|
7
9
|
render() {
|
|
8
10
|
const currentUser = useCurrentUser()
|
|
11
|
+
const {t} = useI18n({namespace: "js.api_maker.super_admin.layout.no_access"})
|
|
9
12
|
|
|
10
13
|
return (
|
|
11
|
-
<
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
<View
|
|
15
|
+
dataSet={{
|
|
16
|
+
component: "super-admin--layout--no-access",
|
|
17
|
+
userRoles: currentUser?.userRoles()?.loaded()?.map((userRole) => userRole.role()?.identifier()).join(", ")
|
|
18
|
+
}}
|
|
14
19
|
>
|
|
15
|
-
{
|
|
16
|
-
</
|
|
20
|
+
{t(".you_dont_have_no_access_to_this_page", {defaultValue: "You don't have access to this page."})}
|
|
21
|
+
</View>
|
|
17
22
|
)
|
|
18
23
|
}
|
|
19
24
|
}))
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
@import "@kaspernj/api-maker/src/super-admin/stylesheets/variables";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[data-component="super-admin--layout"] {
|
|
4
4
|
width: 100%;
|
|
5
5
|
min-height: 100vh;
|
|
6
6
|
background: #fff;
|
|
7
7
|
color: #000;
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
[data-class="app-layout-content-container"] {
|
|
10
10
|
min-height: 100vh;
|
|
11
11
|
background: #f7f7f7;
|
|
12
12
|
|
|
@@ -23,6 +23,8 @@ export default memo(shapeComponent(class ApiMakerSuperAdminModelClassTable exten
|
|
|
23
23
|
const tableConfig = configReader.modelConfig?.table
|
|
24
24
|
const tableProps = {}
|
|
25
25
|
|
|
26
|
+
if (!columns) throw new Error("No columns given")
|
|
27
|
+
|
|
26
28
|
if (tableConfig?.query) tableProps.collection = tableConfig.query
|
|
27
29
|
|
|
28
30
|
return (
|
|
@@ -5,7 +5,9 @@ import PropTypesExact from "prop-types-exact"
|
|
|
5
5
|
import {memo} from "react"
|
|
6
6
|
import {shapeComponent} from "set-state-compare/src/shape-component.js"
|
|
7
7
|
import ShowReflectionLink from "./show-reflection-link"
|
|
8
|
+
import useI18n from "i18n-on-steroids/src/use-i18n.mjs"
|
|
8
9
|
import useQueryParams from "on-location-changed/src/use-query-params"
|
|
10
|
+
import {View} from "react-native"
|
|
9
11
|
|
|
10
12
|
export default memo(shapeComponent(class ApiMakerSuperAdminShowNav extends BaseComponent {
|
|
11
13
|
static propTypes = PropTypesExact({
|
|
@@ -14,23 +16,24 @@ export default memo(shapeComponent(class ApiMakerSuperAdminShowNav extends BaseC
|
|
|
14
16
|
})
|
|
15
17
|
|
|
16
18
|
render() {
|
|
19
|
+
const {t} = useI18n({namespace: "js.api_maker.suprt_admin.show_reflection_page"})
|
|
17
20
|
const {model, modelClass} = this.props
|
|
18
21
|
const queryParams = useQueryParams()
|
|
19
22
|
const reflections = modelClass.reflections()
|
|
20
23
|
|
|
21
24
|
return (
|
|
22
|
-
<
|
|
23
|
-
<
|
|
25
|
+
<View dataSet={{component: "super-admin--show-nav"}}>
|
|
26
|
+
<View>
|
|
24
27
|
<Link to={Params.withParams({model: modelClass.modelClassData().name, model_id: queryParams.model_id})}>
|
|
25
|
-
{
|
|
28
|
+
{t(".general", {defaultValue: "General"})}
|
|
26
29
|
</Link>
|
|
27
|
-
</
|
|
30
|
+
</View>
|
|
28
31
|
{model && reflections.filter((reflection) => reflection.macro() == "has_many").map((reflection) =>
|
|
29
|
-
<
|
|
32
|
+
<View key={reflection.name()}>
|
|
30
33
|
<ShowReflectionLink model={model} modelClass={modelClass} reflection={reflection} />
|
|
31
|
-
</
|
|
34
|
+
</View>
|
|
32
35
|
)}
|
|
33
|
-
</
|
|
36
|
+
</View>
|
|
34
37
|
)
|
|
35
38
|
}
|
|
36
39
|
}))
|
|
@@ -9,6 +9,7 @@ import {memo, useMemo} from "react"
|
|
|
9
9
|
import {shapeComponent} from "set-state-compare/src/shape-component.js"
|
|
10
10
|
import ShowNav from "../show-nav"
|
|
11
11
|
import useModel from "../../use-model"
|
|
12
|
+
import {View} from "react-native"
|
|
12
13
|
|
|
13
14
|
const AttributePresenter = memo(({attribute, model, modelArgs}) => {
|
|
14
15
|
const attributeRowProps = {
|
|
@@ -63,7 +64,9 @@ export default memo(shapeComponent(class ApiMakerSuperAdminShowPage extends Base
|
|
|
63
64
|
|
|
64
65
|
// Select all attributes selected by default because they will be shown by default
|
|
65
66
|
for (const attribute of modelClass.attributes()) {
|
|
66
|
-
if (attribute.isSelectedByDefault()
|
|
67
|
+
if ((attribute.isSelectedByDefault() || attribute.name() == "name") && !modelClassSelect.includes(attribute.name())) {
|
|
68
|
+
modelClassSelect.push(attribute.name())
|
|
69
|
+
}
|
|
67
70
|
}
|
|
68
71
|
|
|
69
72
|
for (const reflection of modelClass.reflections()) {
|
|
@@ -112,7 +115,7 @@ export default memo(shapeComponent(class ApiMakerSuperAdminShowPage extends Base
|
|
|
112
115
|
modelArgs[inflection.camelize(modelClass.modelClassData().name, true)] = model
|
|
113
116
|
|
|
114
117
|
return (
|
|
115
|
-
<
|
|
118
|
+
<View dataSet={{component: "super-admin--show-page"}}>
|
|
116
119
|
{model &&
|
|
117
120
|
<ShowNav model={model} modelClass={modelClass} />
|
|
118
121
|
}
|
|
@@ -123,7 +126,7 @@ export default memo(shapeComponent(class ApiMakerSuperAdminShowPage extends Base
|
|
|
123
126
|
<BelongsToAttributeRow key={reflection.name()} model={model} modelClass={modelClass} reflection={reflection} />
|
|
124
127
|
)}
|
|
125
128
|
{model && extraContent && extraContent(modelArgs)}
|
|
126
|
-
</
|
|
129
|
+
</View>
|
|
127
130
|
)
|
|
128
131
|
}
|
|
129
132
|
}))
|
|
@@ -7,10 +7,12 @@ import ModelClassTable from "./model-class-table"
|
|
|
7
7
|
import {shapeComponent} from "set-state-compare/src/shape-component.js"
|
|
8
8
|
import ShowNav from "./show-nav"
|
|
9
9
|
import useQueryParams from "on-location-changed/src/use-query-params"
|
|
10
|
+
import {View} from "react-native"
|
|
10
11
|
|
|
11
12
|
export default memo(shapeComponent(class ApiMakerSuperAdminShowReflectionPage extends BaseComponent {
|
|
12
13
|
static propTypes = propTypesExact({
|
|
13
|
-
modelClass: PropTypes.func.isRequired
|
|
14
|
+
modelClass: PropTypes.func.isRequired,
|
|
15
|
+
modelId: PropTypes.string.isRequired
|
|
14
16
|
})
|
|
15
17
|
|
|
16
18
|
render() {
|
|
@@ -27,7 +29,7 @@ export default memo(shapeComponent(class ApiMakerSuperAdminShowReflectionPage ex
|
|
|
27
29
|
if (model) collection = model[reflection.name()]()
|
|
28
30
|
|
|
29
31
|
return (
|
|
30
|
-
<
|
|
32
|
+
<View dataSet={{component: "super-admin--show-page"}}>
|
|
31
33
|
{model &&
|
|
32
34
|
<ShowNav model={model} modelClass={modelClass} />
|
|
33
35
|
}
|
|
@@ -38,7 +40,7 @@ export default memo(shapeComponent(class ApiMakerSuperAdminShowReflectionPage ex
|
|
|
38
40
|
modelClass={reflectionModelClass}
|
|
39
41
|
/>
|
|
40
42
|
}
|
|
41
|
-
</
|
|
43
|
+
</View>
|
|
42
44
|
)
|
|
43
45
|
}
|
|
44
46
|
}))
|
package/src/table/table.jsx
CHANGED
|
@@ -21,7 +21,7 @@ import Settings from "./settings"
|
|
|
21
21
|
import {shapeComponent} from "set-state-compare/src/shape-component"
|
|
22
22
|
import TableSettings from "./table-settings"
|
|
23
23
|
import uniqunize from "uniqunize"
|
|
24
|
-
import useBreakpoint from "
|
|
24
|
+
import useBreakpoint from "../use-breakpoint"
|
|
25
25
|
import useCollection from "../use-collection"
|
|
26
26
|
import useQueryParams from "on-location-changed/src/use-query-params.js"
|
|
27
27
|
|
|
@@ -175,7 +175,9 @@ export default memo(shapeComponent(class ApiMakerTable extends BaseComponent {
|
|
|
175
175
|
updateSettingsFullCacheKey = () => this.setState({tableSettingFullCacheKey: this.state.tableSetting.fullCacheKey()})
|
|
176
176
|
|
|
177
177
|
columnsAsArray = () => {
|
|
178
|
-
if (typeof this.props.columns == "function")
|
|
178
|
+
if (typeof this.props.columns == "function") {
|
|
179
|
+
return this.props.columns()
|
|
180
|
+
}
|
|
179
181
|
|
|
180
182
|
return this.props.columns
|
|
181
183
|
}
|
|
File without changes
|