api_maker 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (135) hide show
  1. checksums.yaml +4 -4
  2. data/app/api_maker/api_helpers/api_maker_helpers.rb +5 -0
  3. data/app/api_maker/services/can_can/load_abilities.rb +30 -0
  4. data/app/api_maker/services/devise/sign_in.rb +64 -0
  5. data/app/api_maker/services/devise/sign_out.rb +9 -0
  6. data/app/api_maker/services/models/find_or_create_by.rb +18 -0
  7. data/app/channels/api_maker/subscriptions_channel.rb +33 -2
  8. data/app/controllers/api_maker/base_controller.rb +7 -3
  9. data/app/controllers/api_maker/commands_controller.rb +26 -4
  10. data/app/controllers/api_maker/session_statuses_controller.rb +1 -1
  11. data/app/services/api_maker/abilities_loader.rb +104 -0
  12. data/app/services/api_maker/application_service.rb +2 -1
  13. data/app/services/api_maker/base_command.rb +248 -0
  14. data/app/services/api_maker/collection_command_service.rb +29 -15
  15. data/app/services/api_maker/collection_loader.rb +124 -0
  16. data/app/services/api_maker/command_failed_error.rb +3 -0
  17. data/app/services/api_maker/command_response.rb +17 -6
  18. data/app/services/api_maker/command_service.rb +3 -3
  19. data/app/services/api_maker/create_command.rb +11 -26
  20. data/app/services/api_maker/create_command_service.rb +3 -3
  21. data/app/services/api_maker/database_type.rb +9 -0
  22. data/app/services/api_maker/deep_merge_params.rb +26 -0
  23. data/app/services/api_maker/deserializer.rb +35 -0
  24. data/app/services/api_maker/destroy_command.rb +15 -21
  25. data/app/services/api_maker/destroy_command_service.rb +3 -3
  26. data/app/services/api_maker/generate_react_native_api_service.rb +3 -19
  27. data/app/services/api_maker/include_helpers.rb +17 -0
  28. data/app/services/api_maker/index_command.rb +8 -88
  29. data/app/services/api_maker/index_command_service.rb +5 -5
  30. data/app/services/api_maker/js_method_namer_service.rb +1 -1
  31. data/app/services/api_maker/locals_from_controller.rb +14 -0
  32. data/app/services/api_maker/member_command_service.rb +15 -13
  33. data/app/services/api_maker/model_classes_java_script_generator_service.rb +37 -0
  34. data/app/services/api_maker/model_content_generator_service.rb +17 -21
  35. data/app/services/api_maker/models/save.rb +29 -0
  36. data/app/services/api_maker/models_finder_service.rb +6 -2
  37. data/app/services/api_maker/models_generator_service.rb +6 -43
  38. data/app/services/api_maker/move_components_to_routes.rb +50 -0
  39. data/app/services/api_maker/primary_id_for_model.rb +6 -0
  40. data/app/services/api_maker/reset_indexed_db_service.rb +36 -0
  41. data/app/services/api_maker/routes_file_reloader.rb +20 -0
  42. data/app/services/api_maker/select_columns_on_collection.rb +78 -0
  43. data/app/services/api_maker/select_parser.rb +32 -0
  44. data/app/services/api_maker/service_command.rb +27 -0
  45. data/app/services/api_maker/service_command_service.rb +14 -0
  46. data/app/services/api_maker/simple_model_errors.rb +52 -0
  47. data/app/services/api_maker/update_command.rb +8 -24
  48. data/app/services/api_maker/update_command_service.rb +3 -3
  49. data/app/services/api_maker/valid_command.rb +4 -13
  50. data/app/services/api_maker/valid_command_service.rb +3 -3
  51. data/app/services/api_maker/validation_errors_generator_service.rb +146 -0
  52. data/app/views/api_maker/_data.html.erb +17 -11
  53. data/config/routes.rb +0 -2
  54. data/lib/api_maker/ability.rb +22 -7
  55. data/lib/api_maker/ability_loader.rb +9 -6
  56. data/lib/api_maker/base_collection_instance.rb +15 -0
  57. data/lib/api_maker/base_resource.rb +135 -9
  58. data/lib/api_maker/base_service.rb +14 -0
  59. data/lib/api_maker/collection_serializer.rb +95 -34
  60. data/lib/api_maker/command_spec_helper.rb +41 -11
  61. data/lib/api_maker/configuration.rb +31 -4
  62. data/lib/api_maker/expect_to_able_to_helper.rb +31 -0
  63. data/lib/api_maker/individual_command.rb +24 -9
  64. data/lib/api_maker/javascript/model-template.js.erb +39 -25
  65. data/lib/api_maker/javascript/models.js.erb +6 -0
  66. data/lib/api_maker/loader.rb +1 -1
  67. data/lib/api_maker/memory_storage.rb +1 -1
  68. data/lib/api_maker/model_extensions.rb +34 -18
  69. data/lib/api_maker/permitted_params_argument.rb +5 -1
  70. data/lib/api_maker/preloader.rb +71 -32
  71. data/lib/api_maker/preloader_base.rb +108 -0
  72. data/lib/api_maker/preloader_belongs_to.rb +34 -33
  73. data/lib/api_maker/preloader_has_many.rb +45 -39
  74. data/lib/api_maker/preloader_has_one.rb +30 -47
  75. data/lib/api_maker/railtie.rb +3 -11
  76. data/lib/api_maker/relationship_preloader.rb +42 -0
  77. data/lib/api_maker/resource_routing.rb +18 -4
  78. data/lib/api_maker/result_parser.rb +34 -20
  79. data/lib/api_maker/serializer.rb +53 -22
  80. data/lib/api_maker/spec_helper/browser_logs.rb +14 -0
  81. data/lib/api_maker/spec_helper/execute_collection_command.rb +46 -0
  82. data/lib/api_maker/spec_helper/execute_member_command.rb +52 -0
  83. data/lib/api_maker/spec_helper/expect_no_browser_errors.rb +18 -0
  84. data/lib/api_maker/spec_helper/wait_for_expect.rb +20 -0
  85. data/lib/api_maker/spec_helper/wait_for_flash_message.rb +21 -0
  86. data/lib/api_maker/spec_helper.rb +112 -48
  87. data/lib/api_maker/version.rb +1 -1
  88. data/lib/api_maker.rb +7 -3
  89. metadata +108 -89
  90. data/README.md +0 -476
  91. data/app/controllers/api_maker/devise_controller.rb +0 -60
  92. data/lib/api_maker/base_command.rb +0 -81
  93. data/lib/api_maker/javascript/api.js +0 -92
  94. data/lib/api_maker/javascript/base-model.js +0 -543
  95. data/lib/api_maker/javascript/bootstrap/attribute-row.jsx +0 -16
  96. data/lib/api_maker/javascript/bootstrap/attribute-rows.jsx +0 -47
  97. data/lib/api_maker/javascript/bootstrap/card.jsx +0 -79
  98. data/lib/api_maker/javascript/bootstrap/checkbox.jsx +0 -127
  99. data/lib/api_maker/javascript/bootstrap/checkboxes.jsx +0 -105
  100. data/lib/api_maker/javascript/bootstrap/live-table.jsx +0 -168
  101. data/lib/api_maker/javascript/bootstrap/money-input.jsx +0 -136
  102. data/lib/api_maker/javascript/bootstrap/radio-buttons.jsx +0 -80
  103. data/lib/api_maker/javascript/bootstrap/select.jsx +0 -168
  104. data/lib/api_maker/javascript/bootstrap/string-input.jsx +0 -203
  105. data/lib/api_maker/javascript/cable-connection-pool.js +0 -169
  106. data/lib/api_maker/javascript/cable-subscription-pool.js +0 -111
  107. data/lib/api_maker/javascript/cable-subscription.js +0 -33
  108. data/lib/api_maker/javascript/collection.js +0 -186
  109. data/lib/api_maker/javascript/commands-pool.js +0 -123
  110. data/lib/api_maker/javascript/custom-error.js +0 -14
  111. data/lib/api_maker/javascript/deserializer.js +0 -35
  112. data/lib/api_maker/javascript/devise.js.erb +0 -113
  113. data/lib/api_maker/javascript/error-logger.js +0 -119
  114. data/lib/api_maker/javascript/event-connection.jsx +0 -24
  115. data/lib/api_maker/javascript/event-created.jsx +0 -26
  116. data/lib/api_maker/javascript/event-destroyed.jsx +0 -26
  117. data/lib/api_maker/javascript/event-emitter-listener.jsx +0 -32
  118. data/lib/api_maker/javascript/event-listener.jsx +0 -41
  119. data/lib/api_maker/javascript/event-updated.jsx +0 -26
  120. data/lib/api_maker/javascript/form-data-to-object.js +0 -70
  121. data/lib/api_maker/javascript/included.js +0 -39
  122. data/lib/api_maker/javascript/key-value-store.js +0 -47
  123. data/lib/api_maker/javascript/logger.js +0 -23
  124. data/lib/api_maker/javascript/model-name.js +0 -21
  125. data/lib/api_maker/javascript/models-response-reader.js +0 -43
  126. data/lib/api_maker/javascript/paginate.jsx +0 -128
  127. data/lib/api_maker/javascript/params.js +0 -68
  128. data/lib/api_maker/javascript/resource-route.jsx +0 -75
  129. data/lib/api_maker/javascript/resource-routes.jsx +0 -36
  130. data/lib/api_maker/javascript/result.js +0 -25
  131. data/lib/api_maker/javascript/session-status-updater.js +0 -113
  132. data/lib/api_maker/javascript/sort-link.jsx +0 -88
  133. data/lib/api_maker/javascript/updated-attribute.jsx +0 -60
  134. data/lib/api_maker/preloader_through.rb +0 -101
  135. data/lib/api_maker/relationship_includer.rb +0 -42
@@ -1,127 +0,0 @@
1
- import PropTypes from "prop-types"
2
- import PropTypesExact from "prop-types-exact"
3
- import React from "react"
4
-
5
- const inflection = require("inflection")
6
-
7
- export default class BootstrapCheckbox extends React.Component {
8
- static propTypes = PropTypesExact({
9
- attribute: PropTypes.string,
10
- className: PropTypes.string,
11
- "data-action": PropTypes.string,
12
- "data-target": PropTypes.string,
13
- defaultChecked: PropTypes.bool,
14
- defaultValue: PropTypes.node,
15
- hint: PropTypes.node,
16
- id: PropTypes.string,
17
- label: PropTypes.node,
18
- labelClassName: PropTypes.string,
19
- model: PropTypes.object,
20
- name: PropTypes.string,
21
- onChange: PropTypes.func,
22
- wrapperClassName: PropTypes.string
23
- })
24
-
25
- render() {
26
- let id = this.inputId()
27
-
28
- return (
29
- <div className={this.wrapperClassName()}>
30
- <div className="form-check">
31
- <input defaultValue="0" name={this.inputName()} type="hidden" type="hidden" />
32
- <input
33
- data-target={this.props["data-target"]}
34
- defaultChecked={this.inputDefaultChecked()}
35
- className={this.className()}
36
- data-action={this.props["data-action"]}
37
- defaultValue="1"
38
- id={id}
39
- name={this.inputName()}
40
- onChange={this.props.onChange}
41
- ref="input"
42
- type="checkbox"
43
- />
44
-
45
- {this.label() &&
46
- <label className={this.labelClassName()} htmlFor={id}>
47
- {this.label()}
48
- </label>
49
- }
50
- </div>
51
- {this.props.hint &&
52
- <p className="text-muted">
53
- {this.props.hint}
54
- </p>
55
- }
56
- </div>
57
- )
58
- }
59
-
60
- className() {
61
- var classNames = ["form-check-input"]
62
-
63
- if (this.props.className)
64
- classNames.push(this.props.className)
65
-
66
- return classNames.join(" ")
67
- }
68
-
69
- generatedId() {
70
- return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)
71
- }
72
-
73
- inputDefaultChecked() {
74
- if ("defaultChecked" in this.props) {
75
- return this.props.defaultChecked
76
- } else if (this.props.model) {
77
- if (!this.props.model[this.props.attribute])
78
- throw new Error(`No such attribute: ${this.props.attribute}`)
79
-
80
- return this.props.model[this.props.attribute]()
81
- }
82
- }
83
-
84
- inputId() {
85
- if (this.props.id) {
86
- return this.props.id
87
- } else if (this.props.model) {
88
- return `${this.props.model.modelClassData().paramKey}_${inflection.underscore(this.props.attribute)}`
89
- } else {
90
- return this.generatedId()
91
- }
92
- }
93
-
94
- inputName() {
95
- if (this.props.name) {
96
- return this.props.name
97
- } else if (this.props.model) {
98
- return `${this.props.model.modelClassData().paramKey}[${inflection.underscore(this.props.attribute)}]`
99
- }
100
- }
101
-
102
- wrapperClassName() {
103
- let classNames = ["component-bootstrap-checkbox"]
104
-
105
- if (this.props.wrapperClassName)
106
- classNames.push(this.props.wrapperClassName)
107
-
108
- return classNames.join(" ")
109
- }
110
-
111
- label() {
112
- if (this.props.label) {
113
- return this.props.label
114
- } else if (this.props.model) {
115
- return this.props.model.modelClass().humanAttributeName(this.props.attribute)
116
- }
117
- }
118
-
119
- labelClassName() {
120
- let classNames = ["form-check-label"]
121
-
122
- if (this.props.labelClassName)
123
- classNames.push(this.props.labelClassName)
124
-
125
- return classNames.join(" ")
126
- }
127
- }
@@ -1,105 +0,0 @@
1
- import PropTypes from "prop-types"
2
- import PropTypesExact from "prop-types-exact"
3
- import React from "react"
4
-
5
- const inflection = require("inflection")
6
-
7
- export default class BootstrapCheckboxes extends React.Component {
8
- static propTypes = PropTypesExact({
9
- attribute: PropTypes.string,
10
- defaultValue: PropTypes.array,
11
- label: PropTypes.string,
12
- labelClassName: PropTypes.string,
13
- model: PropTypes.object,
14
- name: PropTypes.string,
15
- options: PropTypes.array.isRequired
16
- })
17
-
18
- render() {
19
- return (
20
- <div className="component-bootstrap-checkboxes form-group">
21
- <label className={this.labelClassName()}>
22
- {this.label()}
23
- </label>
24
-
25
- <input name={this.inputName()} type="hidden" value="" />
26
- {this.props.options.map((option, index) => this.optionElement(option, index))}
27
- </div>
28
- )
29
- }
30
-
31
- inputDefaultValue() {
32
- if (this.props.defaultValue) {
33
- return this.props.defaultValue
34
- } else if (this.props.model) {
35
- if (!this.props.model[this.props.attribute])
36
- throw `No such attribute: ${this.props.attribute}`
37
-
38
- return this.props.model[this.props.attribute]()
39
- }
40
- }
41
-
42
- inputName() {
43
- if (this.props.name) {
44
- return `${this.props.name}[]`
45
- } else if (this.props.model) {
46
- return `${this.props.model.modelClassData().paramKey}[${inflection.underscore(this.props.attribute)}]`
47
- }
48
- }
49
-
50
- isDefaultSelected(option) {
51
- let defaultValue = this.inputDefaultValue()
52
-
53
- if (!defaultValue)
54
- return false
55
-
56
- if (defaultValue.constructor === Array) {
57
- return defaultValue.includes(option)
58
- } else {
59
- return defaultValue == option
60
- }
61
- }
62
-
63
- label() {
64
- if (this.props.label === false) {
65
- return null
66
- } else if (this.props.label) {
67
- return this.props.label
68
- } else if (this.props.model) {
69
- return this.props.model.modelClass().humanAttributeName(this.props.attribute)
70
- }
71
- }
72
-
73
- labelClassName() {
74
- let classNames = []
75
-
76
- if (this.props.labelClassName)
77
- classNames.push(this.props.labelClassName)
78
-
79
- return classNames.join(" ")
80
- }
81
-
82
- generatedId() {
83
- return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)
84
- }
85
-
86
- optionElement(option) {
87
- var id = this.generatedId()
88
-
89
- return (
90
- <div className="checkboxes-option" key={`option-${option[1]}`}>
91
- <input
92
- data-option-value={option[1]}
93
- defaultChecked={this.isDefaultSelected(option[1])}
94
- id={id}
95
- name={this.inputName()}
96
- type="checkbox"
97
- value={option[1]} />
98
-
99
- <label className="ml-1" htmlFor={id}>
100
- {option[0]}
101
- </label>
102
- </div>
103
- )
104
- }
105
- }
@@ -1,168 +0,0 @@
1
- import Collection from "api-maker/collection"
2
- import EventCreated from "api-maker/event-created"
3
- import EventDestroyed from "api-maker/event-destroyed"
4
- import Paginate from "api-maker/paginate"
5
- import Params from "api-maker/params"
6
-
7
- const inflection = require("inflection")
8
-
9
- export default class LiveTable extends React.Component {
10
- static defaultProps = {
11
- preloads: [],
12
- select: {}
13
- }
14
-
15
- static propTypes = PropTypesExact({
16
- className: PropTypes.string,
17
- collection: PropTypes.instanceOf(Collection),
18
- columnsContent: PropTypes.func.isRequired,
19
- defaultParams: PropTypes.object,
20
- destroyMessage: PropTypes.string,
21
- filterContent: PropTypes.func,
22
- filterSubmitLabel: PropTypes.node,
23
- headersContent: PropTypes.func.isRequired,
24
- modelClass: PropTypes.func.isRequired,
25
- preloads: PropTypes.array.isRequired,
26
- queryName: PropTypes.string.isRequired,
27
- select: PropTypes.object
28
- })
29
-
30
- constructor(props) {
31
- super(props)
32
- this.state = {
33
- currentHref: location.href,
34
- queryQName: `${this.props.queryName}_q`,
35
- queryPageName: `${this.props.queryName}_page`
36
- }
37
- }
38
-
39
- componentDidMount() {
40
- this.loadQParams().then(() => this.loadModels())
41
- }
42
-
43
- componentDidUpdate() {
44
- if (this.state.currentHref != location.href) {
45
- var { queryQName } = this.state
46
- var params = Params.parse()
47
- var qParams = params[queryQName] || {}
48
- Params.setCachedParams(queryQName, qParams)
49
- this.setState({currentHref: location.href, qParams}, () => this.loadModels())
50
- }
51
- }
52
-
53
- async loadQParams() {
54
- var { queryQName } = this.state
55
- var qParams = await Params.getCachedParams(queryQName, {default: this.props.defaultParams || {}})
56
- return this.setState({qParams})
57
- }
58
-
59
- async loadModels() {
60
- var params = Params.parse()
61
- var { modelClass, preloads, select } = this.props
62
- var { qParams, queryPageName, queryQName } = this.state
63
- var query
64
-
65
- if (this.props.collection) {
66
- query = this.props.collection
67
- } else {
68
- query = modelClass
69
- }
70
-
71
- query = query
72
- .ransack(qParams)
73
- .searchKey(queryQName)
74
- .page(params[queryPageName])
75
- .pageKey(queryPageName)
76
- .preload(preloads)
77
- .select(select)
78
-
79
- var result = await query.result()
80
-
81
- this.setState({query, result, models: result.models()})
82
- }
83
-
84
- render() {
85
- var { qParams, query, result, models } = this.state
86
-
87
- return (
88
- <div className={this.className()}>
89
- {qParams && query && result && models && this.content()}
90
- </div>
91
- )
92
- }
93
-
94
- content() {
95
- var { filterContent, filterSubmitLabel, modelClass } = this.props
96
- var { qParams, query, result, models } = this.state
97
-
98
- return (
99
- <div className="content-container">
100
- <EventCreated modelClass={modelClass} onCreated={() => this.onModelCreated()} />
101
-
102
- {filterContent &&
103
- <Card className="mb-4">
104
- <form onSubmit={(e) => this.onFilterFormSubmit(e)} ref="filterForm">
105
- {filterContent({qParams})}
106
- <input className="btn btn-primary" label={filterSubmitLabel} type="submit" />
107
- </form>
108
- </Card>
109
- }
110
-
111
- {models.map(model =>
112
- <EventDestroyed key={`event-destroyed-${model.cacheKey()}`} model={model} onDestroyed={(args) => this.onModelDestroyed(args)} />
113
- )}
114
-
115
- <Card className="mb-4" striped table>
116
- <thead>
117
- <tr>
118
- {this.props.headersContent({query})}
119
- </tr>
120
- </thead>
121
- <tbody>
122
- {models.map(model =>
123
- <tr className={`${inflection.singularize(modelClass.modelClassData().collectionName)}-row`} data-model-id={model.id()} key={model.cacheKey()}>
124
- {this.props.columnsContent({model})}
125
- </tr>
126
- )}
127
- </tbody>
128
- </Card>
129
-
130
- <Paginate result={result} />
131
- </div>
132
- )
133
- }
134
-
135
- className() {
136
- var classNames = ["component-api-maker-live-table"]
137
-
138
- if (this.props.className)
139
- classNames.push(this.props.className)
140
-
141
- return classNames.join(" ")
142
- }
143
-
144
- onFilterFormSubmit(e) {
145
- e.preventDefault()
146
-
147
- var qParams = Params.serializeForm(this.refs.filterForm)
148
- var { queryQName } = this.state
149
-
150
- var changeParamsParams = {}
151
- changeParamsParams[queryQName] = qParams
152
-
153
- Params.changeParams(changeParamsParams)
154
- Params.setCachedParams(queryQName, qParams)
155
-
156
- this.setState({currentHref: location.href, qParams}, () => this.loadModels())
157
- }
158
-
159
- onModelCreated() {
160
- this.loadModels()
161
- }
162
-
163
- onModelDestroyed(args) {
164
- this.setState({
165
- models: this.state.models.filter(model => model.id() != args.model.id())
166
- })
167
- }
168
- }
@@ -1,136 +0,0 @@
1
- import Api from "api-maker/api"
2
- import formatNumber from "format-number"
3
- import PropTypes from "prop-types"
4
- import React from "react"
5
-
6
- const inflection = require("inflection")
7
-
8
- export default class BootstrapMoneyInput extends React.Component {
9
- constructor(props) {
10
- super(props)
11
- this.state = {}
12
-
13
- let formatOptions = {
14
- decimal: I18n.t("number.currency.format.separator"),
15
- integerSeparator: I18n.t("number.currency.format.delimiter")
16
- }
17
- this.formatter = formatNumber(formatOptions)
18
- }
19
-
20
- render() {
21
- return (
22
- <div className="component-api-maker-bootstrap-money-input">
23
- <input defaultValue={this.inputDefaultCentsValue()} id={this.inputCentsId()} name={this.inputCentsName()} ref="input" type="hidden" />
24
-
25
- <div className="input-group">
26
- <input
27
- className={this.props.className}
28
- defaultValue={this.inputDefaultValue()}
29
- id={this.inputId()}
30
- onBlur={() => this.setAmount()}
31
- onChange={() => this.setCents()}
32
- onKeyUp={() => this.setCents()}
33
- placeholder={this.props.placeholder}
34
- ref="whole"
35
- type="text"
36
- />
37
- <select className="component-bootstrap-money-input" defaultValue={this.inputCurrencyValue()} id={this.inputCurrencyId()} name={this.inputCurrencyName()} onChange={() => { this.onCurrencyChanged() }} ref="currency">
38
- <option></option>
39
- {this.props.currenciesCollection.map(option => (
40
- <option key={`select-option-${option[1]}`} value={option[1]}>
41
- {this.props.small && option[1]}
42
- {!this.props.small && option[0]}
43
- </option>
44
- ))}
45
- </select>
46
- </div>
47
- </div>
48
- )
49
- }
50
-
51
- inputCurrencyId() {
52
- return `${this.inputId()}_currency`
53
- }
54
-
55
- inputCurrencyName() {
56
- if (this.props.currencyName)
57
- return this.props.currencyName
58
-
59
- return `${this.props.model.modelClassData().paramKey}[${inflection.underscore(this.props.attribute)}_currency]`
60
- }
61
-
62
- inputCurrencyValue() {
63
- let value = this.props.model[this.props.attribute]()
64
-
65
- if (value) {
66
- return MoneyFormatter.currencyFromMoney(value).code
67
- } else {
68
- return "DKK"
69
- }
70
- }
71
-
72
- inputDefaultValue() {
73
- let value = this.props.model[this.props.attribute]()
74
-
75
- if (value) {
76
- return MoneyFormatter.fromMoney({amount: value.amount, currency: this.inputCurrencyValue()}, {decimals: 2, excludeCurrency: true}).toString()
77
- } else {
78
- return ""
79
- }
80
- }
81
-
82
- inputDefaultCentsValue() {
83
- let value = this.props.model[this.props.attribute]()
84
-
85
- if (this.refs.input)
86
- return this.refs.input.value
87
-
88
- if (value)
89
- return MoneyFormatter.amountFromMoney(value)
90
- }
91
-
92
- inputCentsId() {
93
- return `${this.inputId()}_cents`
94
- }
95
-
96
- inputCentsName() {
97
- if (this.props.name)
98
- return this.props.name
99
-
100
- return `${this.props.model.modelClassData().paramKey}[${inflection.underscore(this.props.attribute)}_cents]`
101
- }
102
-
103
- inputId() {
104
- return `${this.props.model.modelClassData().paramKey}_${inflection.underscore(this.props.attribute)}`
105
- }
106
-
107
- onCurrencyChanged() {
108
- if (this.props.onChange)
109
- this.props.onChange()
110
- }
111
-
112
- setAmount() {
113
- if (!this.refs.input.value && this.refs.input.value == "") {
114
- this.refs.whole.value = ""
115
- } else {
116
- let cents = parseFloat(this.refs.input.value)
117
- let formatted = MoneyFormatter.fromMoney({amount: cents, currency: this.inputCurrencyValue()}, {decimals: 2, excludeCurrency: true}).toString()
118
-
119
- this.refs.whole.value = formatted
120
- }
121
- }
122
-
123
- setCents() {
124
- let whole = MoneyFormatter.stringToFloat(this.refs.whole.value)
125
- let cents = parseInt(whole * 100)
126
- let oldCents = parseInt(this.refs.input.value)
127
- this.refs.input.value = cents
128
-
129
- if (this.props.onChange && oldCents != cents)
130
- this.props.onChange()
131
- }
132
- }
133
-
134
- BootstrapMoneyInput.propTypes = {
135
- currenciesCollection: PropTypes.array.isRequired
136
- }
@@ -1,80 +0,0 @@
1
- import PropTypesExact from "prop-types-exact"
2
- import React from "react"
3
-
4
- const inflection = require("inflection")
5
-
6
- export default class BootstrapRadioButtons extends React.Component {
7
- static propTypes = PropTypesExact({
8
- attribute: PropTypes.string,
9
- collection: PropTypes.array.isRequired,
10
- defaultValue: PropTypes.oneOfType([
11
- PropTypes.number,
12
- PropTypes.string
13
- ]),
14
- id: PropTypes.string,
15
- name: PropTypes.string,
16
- model: PropTypes.object,
17
- wrapperClassName: PropTypes.string
18
- })
19
-
20
- render() {
21
- return (
22
- <div className={this.wrapperClassName()}>
23
- <input name={this.inputName()} type="hidden" value="" />
24
- {this.props.collection.map(option => this.optionElement(option))}
25
- </div>
26
- )
27
- }
28
-
29
- inputDefaultValue() {
30
- if (this.props.defaultValue) {
31
- return this.props.defaultValue
32
- } else if (this.props.model) {
33
- if (!this.props.model[this.props.attribute])
34
- throw new Error(`No such attribute: ${this.props.attribute}`)
35
-
36
- return this.props.model[this.props.attribute]()
37
- }
38
- }
39
-
40
- inputName() {
41
- if (this.props.name) {
42
- return this.props.name
43
- } else if (this.props.model) {
44
- return `${this.props.model.modelClassData().paramKey}[${inflection.underscore(this.props.attribute)}]`
45
- }
46
- }
47
-
48
- generatedId() {
49
- return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)
50
- }
51
-
52
- optionElement(option) {
53
- let id = this.generatedId()
54
-
55
- return (
56
- <div key={`option-${option[1]}`}>
57
- <input
58
- data-option-value={option[1]}
59
- defaultChecked={option[1] == this.inputDefaultValue()}
60
- id={id}
61
- name={this.inputName()}
62
- type="radio"
63
- value={option[1]} />
64
-
65
- <label className="ml-1" htmlFor={id}>
66
- {option[0]}
67
- </label>
68
- </div>
69
- )
70
- }
71
-
72
- wrapperClassName() {
73
- var classNames = ["component-bootstrap-radio-buttons"]
74
-
75
- if (this.props.wrapperClassName)
76
- classNames.push(this.props.wrapperClassName)
77
-
78
- return classNames.join(" ")
79
- }
80
- }