@kaspernj/api-maker 1.0.216 → 1.0.219
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 -1
- package/src/base-model.mjs +1 -1
- package/src/bootstrap/attribute-row/basic-style.scss +9 -0
- package/src/bootstrap/attribute-row/index.jsx +84 -0
- package/src/bootstrap/attribute-rows.jsx +27 -0
- package/src/bootstrap/card.jsx +135 -0
- package/src/bootstrap/checkbox.jsx +79 -0
- package/src/bootstrap/checkboxes.jsx +122 -0
- package/src/bootstrap/index.js +0 -0
- package/src/bootstrap/input.jsx +160 -0
- package/src/bootstrap/invalid-feedback.jsx +31 -0
- package/src/bootstrap/live-table/model-row.jsx +150 -0
- package/src/bootstrap/live-table.jsx +399 -0
- package/src/bootstrap/paginate.jsx +153 -0
- package/src/bootstrap/radio-buttons.jsx +87 -0
- package/src/bootstrap/select.jsx +110 -0
- package/src/bootstrap/sort-link.jsx +102 -0
- package/src/collection-loader.jsx +7 -8
- package/src/inputs/auto-submit.mjs +37 -0
- package/src/inputs/checkbox.jsx +97 -0
- package/src/inputs/checkboxes.jsx +113 -0
- package/src/inputs/id-for-component.mjs +15 -0
- package/src/inputs/input-wrapper.jsx +170 -0
- package/src/inputs/input.jsx +235 -0
- package/src/inputs/money.jsx +177 -0
- package/src/inputs/name-for-component.mjs +15 -0
- package/src/inputs/select.jsx +87 -0
- package/src/model-class-require.mjs +1 -1
- package/src/model-name.mjs +6 -2
- package/src/params.mjs +7 -0
- package/src/super-admin/index-page/index.jsx +42 -0
- package/src/super-admin/index.jsx +46 -0
- package/src/super-admin/layout/header/index.jsx +60 -0
- package/src/super-admin/layout/header/style.scss +124 -0
- package/src/super-admin/layout/index.jsx +156 -0
- package/src/super-admin/layout/menu/index.jsx +116 -0
- package/src/super-admin/layout/menu/menu-content.jsx +55 -0
- package/src/super-admin/layout/menu/menu-item/index.jsx +27 -0
- package/src/super-admin/layout/menu/menu-item/style.scss +30 -0
- package/src/super-admin/layout/menu/style.scss +103 -0
- package/src/super-admin/layout/no-access.jsx +16 -0
- package/src/super-admin/layout/style.scss +25 -0
- package/src/super-admin/show-page.jsx +9 -0
- package/src/table/column-identifier.mjs +23 -0
- package/src/table/column-visible.mjs +7 -0
- package/src/table/model-row.jsx +182 -0
- package/src/table/select-calculator.mjs +48 -0
- package/src/table/style.scss +72 -0
- package/src/table/table-settings.js +175 -0
- package/src/table/table.jsx +498 -0
- package/src/table/variables.scss +11 -0
- package/src/table/with-breakpoint.jsx +48 -0
package/package.json
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
]
|
|
17
17
|
},
|
|
18
18
|
"name": "@kaspernj/api-maker",
|
|
19
|
-
"version": "1.0.
|
|
19
|
+
"version": "1.0.219",
|
|
20
20
|
"type": "module",
|
|
21
21
|
"description": "",
|
|
22
22
|
"main": "index.js",
|
|
@@ -49,6 +49,7 @@
|
|
|
49
49
|
"js-money": ">= 0.6.3",
|
|
50
50
|
"numberable": ">= 1.0.0",
|
|
51
51
|
"object-to-formdata": ">= 4.1.0",
|
|
52
|
+
"on-location-changed": ">= 1.0.7",
|
|
52
53
|
"qs": ">= 6.9.3",
|
|
53
54
|
"replaceall": ">= 0.1.6",
|
|
54
55
|
"strftime": ">= 0.10.0",
|
package/src/base-model.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import AttributeNotLoadedError from "./attribute-not-loaded-error.mjs"
|
|
2
2
|
import Collection from "./collection.mjs"
|
|
3
3
|
import CommandsPool from "./commands-pool.mjs"
|
|
4
|
-
import Config from "
|
|
4
|
+
import Config from "./config.mjs"
|
|
5
5
|
import CustomError from "./custom-error.mjs"
|
|
6
6
|
import {digg} from "diggerize"
|
|
7
7
|
import FormDataObjectizer from "form-data-objectizer"
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import classNames from "classnames"
|
|
2
|
+
import {digg} from "diggerize"
|
|
3
|
+
import MoneyFormatter from "../../money-formatter"
|
|
4
|
+
import PropTypes from "prop-types"
|
|
5
|
+
import React from "react"
|
|
6
|
+
import strftime from "strftime"
|
|
7
|
+
|
|
8
|
+
export default class ApiMakerBootstrapAttributeRow extends React.PureComponent {
|
|
9
|
+
static defaultProps = {
|
|
10
|
+
checkIfAttributeLoaded: false
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
static propTypes = {
|
|
14
|
+
attribute: PropTypes.string,
|
|
15
|
+
checkIfAttributeLoaded: PropTypes.bool.isRequired,
|
|
16
|
+
children: PropTypes.node,
|
|
17
|
+
identifier: PropTypes.string,
|
|
18
|
+
label: PropTypes.node,
|
|
19
|
+
model: PropTypes.object,
|
|
20
|
+
value: PropTypes.node
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
render () {
|
|
24
|
+
const {attribute, checkIfAttributeLoaded, children, className, identifier, label, model, value, ...restProps} = this.props
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<div
|
|
28
|
+
className={classNames(className, "component-api-maker-attribute-row")}
|
|
29
|
+
data-attribute={attribute}
|
|
30
|
+
data-identifier={identifier}
|
|
31
|
+
{...restProps}
|
|
32
|
+
>
|
|
33
|
+
<div className="attribute-row-label">
|
|
34
|
+
{this.label()}
|
|
35
|
+
</div>
|
|
36
|
+
<div className="attribute-row-value">
|
|
37
|
+
{this.value()}
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
label() {
|
|
44
|
+
const {attribute, label, model} = this.props
|
|
45
|
+
|
|
46
|
+
if ("label" in this.props) return label
|
|
47
|
+
if (attribute && model) return model.constructor.humanAttributeName(attribute)
|
|
48
|
+
|
|
49
|
+
throw new Error("Couldn't figure out label")
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
value() {
|
|
53
|
+
const {attribute, checkIfAttributeLoaded, children, model} = this.props
|
|
54
|
+
|
|
55
|
+
if (children) return children
|
|
56
|
+
|
|
57
|
+
if (attribute && !(attribute in model))
|
|
58
|
+
throw new Error(`Attribute not found: ${digg(model.modelClassData(), "name")}#${attribute}`)
|
|
59
|
+
|
|
60
|
+
if (attribute && checkIfAttributeLoaded && !model.isAttributeLoaded(attribute))
|
|
61
|
+
return null
|
|
62
|
+
|
|
63
|
+
if (attribute && model) {
|
|
64
|
+
const value = model[attribute]()
|
|
65
|
+
|
|
66
|
+
return this.valueContent(value)
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
valueContent(value) {
|
|
71
|
+
if (value instanceof Date) {
|
|
72
|
+
return strftime("%Y-%m-%d %H:%M", value)
|
|
73
|
+
} else if (typeof value === "boolean") {
|
|
74
|
+
if (value)
|
|
75
|
+
return I18n.t("js.shared.yes")
|
|
76
|
+
|
|
77
|
+
return I18n.t("js.shared.no")
|
|
78
|
+
} else if (MoneyFormatter.isMoney(value)) {
|
|
79
|
+
return MoneyFormatter.format(value)
|
|
80
|
+
} else {
|
|
81
|
+
return value
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import AttributeRow from "./attribute-row"
|
|
2
|
+
import {digs} from "diggerize"
|
|
3
|
+
import PropTypes from "prop-types"
|
|
4
|
+
import propTypesExact from "prop-types-exact"
|
|
5
|
+
import React from "react"
|
|
6
|
+
|
|
7
|
+
export default class ApiMakerBootstrapAttributeRows extends React.PureComponent {
|
|
8
|
+
static defaultProps = {
|
|
9
|
+
checkIfAttributeLoaded: false
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
static propTypes = propTypesExact({
|
|
13
|
+
attributes: PropTypes.array.isRequired,
|
|
14
|
+
checkIfAttributeLoaded: PropTypes.bool.isRequired,
|
|
15
|
+
model: PropTypes.object.isRequired
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
classObject = this.props.model.modelClass()
|
|
19
|
+
|
|
20
|
+
render () {
|
|
21
|
+
const {attributes, checkIfAttributeLoaded, model} = digs(this.props, "attributes", "checkIfAttributeLoaded", "model")
|
|
22
|
+
|
|
23
|
+
return attributes.map((attribute) =>
|
|
24
|
+
<AttributeRow attribute={attribute} checkIfAttributeLoaded={checkIfAttributeLoaded} key={`attribute-${attribute}`} model={model} />
|
|
25
|
+
)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import {digs} from "diggerize"
|
|
2
|
+
import PropTypes from "prop-types"
|
|
3
|
+
import React from "react"
|
|
4
|
+
|
|
5
|
+
export default class ApiMakerBootstrapCard extends React.PureComponent {
|
|
6
|
+
static defaultProps = {
|
|
7
|
+
defaultExpanded: true,
|
|
8
|
+
expandable: false,
|
|
9
|
+
expandableHide: false,
|
|
10
|
+
responsiveTable: true,
|
|
11
|
+
table: false
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
static propTypes = {
|
|
15
|
+
className: PropTypes.string,
|
|
16
|
+
children: PropTypes.node,
|
|
17
|
+
controls: PropTypes.node,
|
|
18
|
+
defaultExpanded: PropTypes.bool.isRequired,
|
|
19
|
+
expandable: PropTypes.bool.isRequired,
|
|
20
|
+
expandableHide: PropTypes.bool.isRequired,
|
|
21
|
+
header: PropTypes.node,
|
|
22
|
+
striped: PropTypes.bool,
|
|
23
|
+
responsiveTable: PropTypes.bool.isRequired,
|
|
24
|
+
table: PropTypes.bool.isRequired
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
constructor (props) {
|
|
28
|
+
super(props)
|
|
29
|
+
this.state = {
|
|
30
|
+
expanded: props.defaultExpanded
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
render () {
|
|
35
|
+
const {
|
|
36
|
+
children,
|
|
37
|
+
className,
|
|
38
|
+
controls,
|
|
39
|
+
defaultExpanded,
|
|
40
|
+
expandable,
|
|
41
|
+
expandableHide,
|
|
42
|
+
header,
|
|
43
|
+
responsiveTable,
|
|
44
|
+
striped,
|
|
45
|
+
table,
|
|
46
|
+
...restProps
|
|
47
|
+
} = this.props
|
|
48
|
+
const {expanded} = digs(this.state, "expanded")
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<div className={this.classNames()} ref="card" {...restProps}>
|
|
52
|
+
{(controls || expandable || header) &&
|
|
53
|
+
<div className={`card-header d-flex ${!expanded && "border-bottom-0"}`}>
|
|
54
|
+
<div style={{alignSelf: "center", marginRight: "auto"}}>
|
|
55
|
+
{header}
|
|
56
|
+
</div>
|
|
57
|
+
{(controls || expandable) &&
|
|
58
|
+
<div style={{alignSelf: "center"}}>
|
|
59
|
+
{controls}
|
|
60
|
+
{expandable && expanded &&
|
|
61
|
+
<a className="collapse-card-button text-muted" href="#" onClick={this.onCollapseClicked}>
|
|
62
|
+
<i className="la la-angle-up" />
|
|
63
|
+
</a>
|
|
64
|
+
}
|
|
65
|
+
{expandable && !expanded &&
|
|
66
|
+
<a className="expand-card-button text-muted" href="#" onClick={this.onExpandClicked}>
|
|
67
|
+
<i className="la la-angle-down" />
|
|
68
|
+
</a>
|
|
69
|
+
}
|
|
70
|
+
</div>
|
|
71
|
+
}
|
|
72
|
+
</div>
|
|
73
|
+
}
|
|
74
|
+
{(expanded || expandableHide) &&
|
|
75
|
+
<div className={this.bodyClassNames()}>
|
|
76
|
+
{table &&
|
|
77
|
+
<table className={this.tableClassNames()}>
|
|
78
|
+
{children}
|
|
79
|
+
</table>
|
|
80
|
+
}
|
|
81
|
+
{!table && children}
|
|
82
|
+
</div>
|
|
83
|
+
}
|
|
84
|
+
</div>
|
|
85
|
+
)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
classNames () {
|
|
89
|
+
const classNames = ["component-bootstrap-card", "card", "card-default"]
|
|
90
|
+
|
|
91
|
+
if (this.props.className)
|
|
92
|
+
classNames.push(this.props.className)
|
|
93
|
+
|
|
94
|
+
return classNames.join(" ")
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
bodyClassNames () {
|
|
98
|
+
const {expandableHide, responsiveTable, table} = digs(this.props, "expandableHide", "responsiveTable", "table")
|
|
99
|
+
const {expanded} = digs(this.state, "expanded")
|
|
100
|
+
const classNames = ["card-body"]
|
|
101
|
+
|
|
102
|
+
if (!expanded && expandableHide) {
|
|
103
|
+
classNames.push("d-none")
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (table) {
|
|
107
|
+
if (responsiveTable){
|
|
108
|
+
classNames.push("table-responsive")
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
classNames.push("p-0")
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return classNames.join(" ")
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
onCollapseClicked = (e) => {
|
|
118
|
+
e.preventDefault()
|
|
119
|
+
this.setState({expanded: false})
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
onExpandClicked = (e) => {
|
|
123
|
+
e.preventDefault()
|
|
124
|
+
this.setState({expanded: true})
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
tableClassNames () {
|
|
128
|
+
const classNames = ["table", "table-hover", "mb-0", "w-100"]
|
|
129
|
+
|
|
130
|
+
if (this.props.striped)
|
|
131
|
+
classNames.push("table-striped")
|
|
132
|
+
|
|
133
|
+
return classNames.join(" ")
|
|
134
|
+
}
|
|
135
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import {Checkbox} from "../inputs/checkbox"
|
|
2
|
+
import classNames from "classnames"
|
|
3
|
+
import {digs} from "diggerize"
|
|
4
|
+
import inputWrapper from "../inputs/input-wrapper"
|
|
5
|
+
import InvalidFeedback from "./invalid-feedback"
|
|
6
|
+
import PropTypes from "prop-types"
|
|
7
|
+
import React from "react"
|
|
8
|
+
|
|
9
|
+
class ApiMakerBootstrapCheckbox extends React.PureComponent {
|
|
10
|
+
static defaultProps = {
|
|
11
|
+
defaultValue: 1,
|
|
12
|
+
zeroInput: true
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
static propTypes = {
|
|
16
|
+
attribute: PropTypes.string,
|
|
17
|
+
className: PropTypes.string,
|
|
18
|
+
defaultChecked: PropTypes.bool,
|
|
19
|
+
defaultValue: PropTypes.node,
|
|
20
|
+
hint: PropTypes.node,
|
|
21
|
+
id: PropTypes.string,
|
|
22
|
+
label: PropTypes.node,
|
|
23
|
+
labelClassName: PropTypes.string,
|
|
24
|
+
model: PropTypes.object,
|
|
25
|
+
name: PropTypes.string,
|
|
26
|
+
onChange: PropTypes.func,
|
|
27
|
+
wrapperClassName: PropTypes.string,
|
|
28
|
+
zeroInput: PropTypes.bool
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
render () {
|
|
32
|
+
const {className, hint, id, inputProps, inputRef, label, labelClassName, wrapperClassName, wrapperOpts, ...restProps} = this.props
|
|
33
|
+
const {errors} = digs(wrapperOpts, "errors")
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<div className={this.wrapperClassName()}>
|
|
37
|
+
<div className="form-check">
|
|
38
|
+
<Checkbox
|
|
39
|
+
className={classNames("form-check-input", className, {"is-invalid": errors.length > 0})}
|
|
40
|
+
inputProps={inputProps}
|
|
41
|
+
wrapperOpts={wrapperOpts}
|
|
42
|
+
{...restProps}
|
|
43
|
+
/>
|
|
44
|
+
{wrapperOpts.label &&
|
|
45
|
+
<label className={this.labelClassName()} htmlFor={inputProps.id}>
|
|
46
|
+
{wrapperOpts.label}
|
|
47
|
+
</label>
|
|
48
|
+
}
|
|
49
|
+
{hint &&
|
|
50
|
+
<p className="text-muted">
|
|
51
|
+
{hint}
|
|
52
|
+
</p>
|
|
53
|
+
}
|
|
54
|
+
{errors.length > 0 && <InvalidFeedback errors={errors} />}
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
labelClassName () {
|
|
61
|
+
const classNames = ["form-check-label"]
|
|
62
|
+
|
|
63
|
+
if (this.props.labelClassName)
|
|
64
|
+
classNames.push(this.props.labelClassName)
|
|
65
|
+
|
|
66
|
+
return classNames.join(" ")
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
wrapperClassName () {
|
|
70
|
+
const classNames = ["component-bootstrap-checkbox", "form-group"]
|
|
71
|
+
|
|
72
|
+
if (this.props.wrapperClassName)
|
|
73
|
+
classNames.push(this.props.wrapperClassName)
|
|
74
|
+
|
|
75
|
+
return classNames.join(" ")
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export default inputWrapper(ApiMakerBootstrapCheckbox, {type: "checkbox"})
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import {digs} from "diggerize"
|
|
2
|
+
import inputWrapper from "../inputs/input-wrapper"
|
|
3
|
+
import inflection from "inflection"
|
|
4
|
+
import InvalidFeedback from "./invalid-feedback"
|
|
5
|
+
import PropTypes from "prop-types"
|
|
6
|
+
import propTypesExact from "prop-types-exact"
|
|
7
|
+
import React from "react"
|
|
8
|
+
|
|
9
|
+
class ApiMakerBootstrapCheckboxes extends React.PureComponent {
|
|
10
|
+
static propTypes = propTypesExact({
|
|
11
|
+
attribute: PropTypes.string,
|
|
12
|
+
defaultValue: PropTypes.array,
|
|
13
|
+
inputProps: PropTypes.object.isRequired,
|
|
14
|
+
label: PropTypes.string,
|
|
15
|
+
labelClassName: PropTypes.string,
|
|
16
|
+
model: PropTypes.object,
|
|
17
|
+
name: PropTypes.string,
|
|
18
|
+
onChange: PropTypes.func,
|
|
19
|
+
options: PropTypes.array.isRequired,
|
|
20
|
+
wrapperOpts: PropTypes.object.isRequired
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
render () {
|
|
24
|
+
return (
|
|
25
|
+
<div className="component-bootstrap-checkboxes form-group">
|
|
26
|
+
<label className={this.labelClassName()}>
|
|
27
|
+
{this.props.wrapperOpts.label}
|
|
28
|
+
</label>
|
|
29
|
+
|
|
30
|
+
<input name={this.inputName()} ref={this.props.inputProps.ref} type="hidden" value="" />
|
|
31
|
+
{this.props.options.map((option, index) => this.optionElement(option, index))}
|
|
32
|
+
</div>
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
inputDefaultValue () {
|
|
37
|
+
const {attribute, defaultValue, model} = this.props
|
|
38
|
+
|
|
39
|
+
if (defaultValue) {
|
|
40
|
+
return defaultValue
|
|
41
|
+
} else if (attribute && model) {
|
|
42
|
+
if (!model[attribute])
|
|
43
|
+
throw `No such attribute: ${attribute}`
|
|
44
|
+
|
|
45
|
+
return this.props.model[attribute]()
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
inputCheckboxClassName () {
|
|
50
|
+
const classNames = []
|
|
51
|
+
|
|
52
|
+
if (this.props.wrapperOpts.errors.length > 0) classNames.push("is-invalid")
|
|
53
|
+
|
|
54
|
+
return classNames.join(" ")
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
inputName () {
|
|
58
|
+
if (this.props.name) {
|
|
59
|
+
return `${this.props.name}[]`
|
|
60
|
+
} else if (this.props.model) {
|
|
61
|
+
return `${this.props.model.modelClassData().paramKey}[${inflection.underscore(this.props.attribute)}]`
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
isDefaultSelected (option) {
|
|
66
|
+
let defaultValue = this.inputDefaultValue()
|
|
67
|
+
|
|
68
|
+
if (!defaultValue) return false
|
|
69
|
+
|
|
70
|
+
if (defaultValue.constructor === Array) {
|
|
71
|
+
return defaultValue.includes(option)
|
|
72
|
+
} else {
|
|
73
|
+
return defaultValue == option
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
labelClassName () {
|
|
78
|
+
const classNames = []
|
|
79
|
+
|
|
80
|
+
if (this.props.labelClassName) classNames.push(this.props.labelClassName)
|
|
81
|
+
|
|
82
|
+
return classNames.join(" ")
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
generatedId () {
|
|
86
|
+
if (!this.generatedIdValue)
|
|
87
|
+
this.generatedIdValue = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)
|
|
88
|
+
|
|
89
|
+
return this.generatedIdValue
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
optionElement (option, index) {
|
|
93
|
+
const {onChange, options, wrapperOpts} = this.props
|
|
94
|
+
const {errors} = digs(wrapperOpts, "errors")
|
|
95
|
+
const id = `${this.generatedId()}-${index}`
|
|
96
|
+
|
|
97
|
+
return (
|
|
98
|
+
<div className="checkboxes-option" key={`option-${option[1]}`}>
|
|
99
|
+
<input
|
|
100
|
+
className={this.inputCheckboxClassName()}
|
|
101
|
+
data-option-value={option[1]}
|
|
102
|
+
defaultChecked={this.isDefaultSelected(option[1])}
|
|
103
|
+
id={id}
|
|
104
|
+
name={this.inputName()}
|
|
105
|
+
onChange={onChange}
|
|
106
|
+
type="checkbox"
|
|
107
|
+
value={option[1]}
|
|
108
|
+
/>
|
|
109
|
+
|
|
110
|
+
<label className="ml-1" htmlFor={id}>
|
|
111
|
+
{option[0]}
|
|
112
|
+
</label>
|
|
113
|
+
|
|
114
|
+
{(index + 1) == options.length && errors.length > 0 &&
|
|
115
|
+
<InvalidFeedback errors={errors} />
|
|
116
|
+
}
|
|
117
|
+
</div>
|
|
118
|
+
)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export default inputWrapper(ApiMakerBootstrapCheckboxes)
|
|
File without changes
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import {digs} from "diggerize"
|
|
2
|
+
import inputWrapper from "../inputs/input-wrapper"
|
|
3
|
+
import {Input} from "../inputs/input"
|
|
4
|
+
import InvalidFeedback from "./invalid-feedback"
|
|
5
|
+
import Money from "../inputs/money"
|
|
6
|
+
import PropTypes from "prop-types"
|
|
7
|
+
import React from "react"
|
|
8
|
+
|
|
9
|
+
class ApiMakerBootstrapInput extends React.PureComponent {
|
|
10
|
+
static propTypes = {
|
|
11
|
+
append: PropTypes.node,
|
|
12
|
+
appendText: PropTypes.node,
|
|
13
|
+
attribute: PropTypes.string,
|
|
14
|
+
className: PropTypes.string,
|
|
15
|
+
currenciesCollection: PropTypes.array,
|
|
16
|
+
currencyName: PropTypes.string,
|
|
17
|
+
hint: PropTypes.node,
|
|
18
|
+
hintBottom: PropTypes.node,
|
|
19
|
+
id: PropTypes.string,
|
|
20
|
+
label: PropTypes.node,
|
|
21
|
+
labelClassName: PropTypes.string,
|
|
22
|
+
model: PropTypes.object,
|
|
23
|
+
name: PropTypes.string,
|
|
24
|
+
placeholder: PropTypes.node,
|
|
25
|
+
prepend: PropTypes.node,
|
|
26
|
+
prependText: PropTypes.node,
|
|
27
|
+
small: PropTypes.bool,
|
|
28
|
+
type: PropTypes.string,
|
|
29
|
+
wrapperClassName: PropTypes.string
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
render () {
|
|
33
|
+
const {
|
|
34
|
+
append,
|
|
35
|
+
appendText,
|
|
36
|
+
attribute,
|
|
37
|
+
className,
|
|
38
|
+
currenciesCollection,
|
|
39
|
+
currencyName,
|
|
40
|
+
hint,
|
|
41
|
+
hintBottom,
|
|
42
|
+
id,
|
|
43
|
+
inputClassName,
|
|
44
|
+
inputProps,
|
|
45
|
+
inputRef,
|
|
46
|
+
label,
|
|
47
|
+
labelClassName,
|
|
48
|
+
model,
|
|
49
|
+
name,
|
|
50
|
+
prepend,
|
|
51
|
+
prependText,
|
|
52
|
+
type,
|
|
53
|
+
wrapperClassName,
|
|
54
|
+
wrapperOpts,
|
|
55
|
+
...restProps
|
|
56
|
+
} = this.props
|
|
57
|
+
const {ref, ...forwardedInputProps} = inputProps
|
|
58
|
+
const {errors} = digs(wrapperOpts, "errors")
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<div className={this.wrapperClassName()} ref="wrapper">
|
|
62
|
+
{wrapperOpts.label &&
|
|
63
|
+
<label className={this.labelClassName()} htmlFor={inputProps.id}>
|
|
64
|
+
{wrapperOpts.label}
|
|
65
|
+
</label>
|
|
66
|
+
}
|
|
67
|
+
{hint &&
|
|
68
|
+
<span className="form-text text-muted font-smoothing font-xs">
|
|
69
|
+
{hint}
|
|
70
|
+
</span>
|
|
71
|
+
}
|
|
72
|
+
{type == "money" &&
|
|
73
|
+
<Money
|
|
74
|
+
attribute={attribute}
|
|
75
|
+
currenciesCollection={currenciesCollection}
|
|
76
|
+
currencyName={currencyName}
|
|
77
|
+
model={model}
|
|
78
|
+
name={inputProps.name}
|
|
79
|
+
className={this.inputClassName()}
|
|
80
|
+
onChange={this.props.onChange}
|
|
81
|
+
placeholder={this.props.placeholder}
|
|
82
|
+
small={this.props.small}
|
|
83
|
+
ref="money"
|
|
84
|
+
/>
|
|
85
|
+
}
|
|
86
|
+
{type != "money" &&
|
|
87
|
+
<div className="input-group">
|
|
88
|
+
{(prepend || prependText) &&
|
|
89
|
+
<div className="input-group-prepend">
|
|
90
|
+
{prependText &&
|
|
91
|
+
<span className="input-group-text">
|
|
92
|
+
{prependText}
|
|
93
|
+
</span>
|
|
94
|
+
}
|
|
95
|
+
{prepend}
|
|
96
|
+
</div>
|
|
97
|
+
}
|
|
98
|
+
<Input
|
|
99
|
+
attribute={attribute}
|
|
100
|
+
className={this.inputClassName()}
|
|
101
|
+
inputProps={inputProps}
|
|
102
|
+
model={model}
|
|
103
|
+
wrapperOpts={wrapperOpts}
|
|
104
|
+
{...forwardedInputProps}
|
|
105
|
+
{...restProps}
|
|
106
|
+
/>
|
|
107
|
+
{(append || appendText) &&
|
|
108
|
+
<div className="input-group-append">
|
|
109
|
+
{appendText &&
|
|
110
|
+
<span className="input-group-text">
|
|
111
|
+
{appendText}
|
|
112
|
+
</span>
|
|
113
|
+
}
|
|
114
|
+
{append}
|
|
115
|
+
</div>
|
|
116
|
+
}
|
|
117
|
+
{errors.length > 0 && <InvalidFeedback errors={errors} />}
|
|
118
|
+
</div>
|
|
119
|
+
}
|
|
120
|
+
{hintBottom &&
|
|
121
|
+
<span className="form-text text-muted font-smoothing font-xs">
|
|
122
|
+
{hintBottom}
|
|
123
|
+
</span>
|
|
124
|
+
}
|
|
125
|
+
</div>
|
|
126
|
+
)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
inputClassName () {
|
|
130
|
+
const classNames = ["form-control"]
|
|
131
|
+
|
|
132
|
+
if (this.props.className)
|
|
133
|
+
classNames.push(this.props.className)
|
|
134
|
+
|
|
135
|
+
if (this.props.wrapperOpts.errors.length > 0)
|
|
136
|
+
classNames.push("is-invalid")
|
|
137
|
+
|
|
138
|
+
return classNames.join(" ")
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
labelClassName () {
|
|
142
|
+
const classNames = []
|
|
143
|
+
|
|
144
|
+
if (this.props.labelClassName)
|
|
145
|
+
classNames.push(this.props.labelClassName)
|
|
146
|
+
|
|
147
|
+
return classNames.join(" ")
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
wrapperClassName () {
|
|
151
|
+
const classNames = ["form-group", "component-bootstrap-string-input"]
|
|
152
|
+
|
|
153
|
+
if (this.props.wrapperClassName)
|
|
154
|
+
classNames.push(this.props.wrapperClassName)
|
|
155
|
+
|
|
156
|
+
return classNames.join(" ")
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export default inputWrapper(ApiMakerBootstrapInput)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {digs} from "diggerize"
|
|
2
|
+
import PropTypes from "prop-types"
|
|
3
|
+
import propTypesExact from "prop-types-exact"
|
|
4
|
+
import React from "react"
|
|
5
|
+
|
|
6
|
+
export default class ApiMakerBootstrapInvalidFeedback extends React.PureComponent {
|
|
7
|
+
static propTypes = propTypesExact({
|
|
8
|
+
errors: PropTypes.array.isRequired
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
render () {
|
|
12
|
+
return (
|
|
13
|
+
<div className="invalid-feedback">
|
|
14
|
+
{this.errorMessages().join(". ")}
|
|
15
|
+
</div>
|
|
16
|
+
)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
errorMessages () {
|
|
20
|
+
const {errors} = digs(this.props, "errors")
|
|
21
|
+
const errorMessages = []
|
|
22
|
+
|
|
23
|
+
for (const error of errors) {
|
|
24
|
+
for (const errorMessage of error.getErrorMessages()) {
|
|
25
|
+
errorMessages.push(errorMessage)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return errorMessages
|
|
30
|
+
}
|
|
31
|
+
}
|