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.
- checksums.yaml +4 -4
- data/app/api_maker/api_helpers/api_maker_helpers.rb +5 -0
- data/app/api_maker/services/can_can/load_abilities.rb +30 -0
- data/app/api_maker/services/devise/sign_in.rb +64 -0
- data/app/api_maker/services/devise/sign_out.rb +9 -0
- data/app/api_maker/services/models/find_or_create_by.rb +18 -0
- data/app/channels/api_maker/subscriptions_channel.rb +33 -2
- data/app/controllers/api_maker/base_controller.rb +7 -3
- data/app/controllers/api_maker/commands_controller.rb +26 -4
- data/app/controllers/api_maker/session_statuses_controller.rb +1 -1
- data/app/services/api_maker/abilities_loader.rb +104 -0
- data/app/services/api_maker/application_service.rb +2 -1
- data/app/services/api_maker/base_command.rb +248 -0
- data/app/services/api_maker/collection_command_service.rb +29 -15
- data/app/services/api_maker/collection_loader.rb +124 -0
- data/app/services/api_maker/command_failed_error.rb +3 -0
- data/app/services/api_maker/command_response.rb +17 -6
- data/app/services/api_maker/command_service.rb +3 -3
- data/app/services/api_maker/create_command.rb +11 -26
- data/app/services/api_maker/create_command_service.rb +3 -3
- data/app/services/api_maker/database_type.rb +9 -0
- data/app/services/api_maker/deep_merge_params.rb +26 -0
- data/app/services/api_maker/deserializer.rb +35 -0
- data/app/services/api_maker/destroy_command.rb +15 -21
- data/app/services/api_maker/destroy_command_service.rb +3 -3
- data/app/services/api_maker/generate_react_native_api_service.rb +3 -19
- data/app/services/api_maker/include_helpers.rb +17 -0
- data/app/services/api_maker/index_command.rb +8 -88
- data/app/services/api_maker/index_command_service.rb +5 -5
- data/app/services/api_maker/js_method_namer_service.rb +1 -1
- data/app/services/api_maker/locals_from_controller.rb +14 -0
- data/app/services/api_maker/member_command_service.rb +15 -13
- data/app/services/api_maker/model_classes_java_script_generator_service.rb +37 -0
- data/app/services/api_maker/model_content_generator_service.rb +17 -21
- data/app/services/api_maker/models/save.rb +29 -0
- data/app/services/api_maker/models_finder_service.rb +6 -2
- data/app/services/api_maker/models_generator_service.rb +6 -43
- data/app/services/api_maker/move_components_to_routes.rb +50 -0
- data/app/services/api_maker/primary_id_for_model.rb +6 -0
- data/app/services/api_maker/reset_indexed_db_service.rb +36 -0
- data/app/services/api_maker/routes_file_reloader.rb +20 -0
- data/app/services/api_maker/select_columns_on_collection.rb +78 -0
- data/app/services/api_maker/select_parser.rb +32 -0
- data/app/services/api_maker/service_command.rb +27 -0
- data/app/services/api_maker/service_command_service.rb +14 -0
- data/app/services/api_maker/simple_model_errors.rb +52 -0
- data/app/services/api_maker/update_command.rb +8 -24
- data/app/services/api_maker/update_command_service.rb +3 -3
- data/app/services/api_maker/valid_command.rb +4 -13
- data/app/services/api_maker/valid_command_service.rb +3 -3
- data/app/services/api_maker/validation_errors_generator_service.rb +146 -0
- data/app/views/api_maker/_data.html.erb +17 -11
- data/config/routes.rb +0 -2
- data/lib/api_maker/ability.rb +22 -7
- data/lib/api_maker/ability_loader.rb +9 -6
- data/lib/api_maker/base_collection_instance.rb +15 -0
- data/lib/api_maker/base_resource.rb +135 -9
- data/lib/api_maker/base_service.rb +14 -0
- data/lib/api_maker/collection_serializer.rb +95 -34
- data/lib/api_maker/command_spec_helper.rb +41 -11
- data/lib/api_maker/configuration.rb +31 -4
- data/lib/api_maker/expect_to_able_to_helper.rb +31 -0
- data/lib/api_maker/individual_command.rb +24 -9
- data/lib/api_maker/javascript/model-template.js.erb +39 -25
- data/lib/api_maker/javascript/models.js.erb +6 -0
- data/lib/api_maker/loader.rb +1 -1
- data/lib/api_maker/memory_storage.rb +1 -1
- data/lib/api_maker/model_extensions.rb +34 -18
- data/lib/api_maker/permitted_params_argument.rb +5 -1
- data/lib/api_maker/preloader.rb +71 -32
- data/lib/api_maker/preloader_base.rb +108 -0
- data/lib/api_maker/preloader_belongs_to.rb +34 -33
- data/lib/api_maker/preloader_has_many.rb +45 -39
- data/lib/api_maker/preloader_has_one.rb +30 -47
- data/lib/api_maker/railtie.rb +3 -11
- data/lib/api_maker/relationship_preloader.rb +42 -0
- data/lib/api_maker/resource_routing.rb +18 -4
- data/lib/api_maker/result_parser.rb +34 -20
- data/lib/api_maker/serializer.rb +53 -22
- data/lib/api_maker/spec_helper/browser_logs.rb +14 -0
- data/lib/api_maker/spec_helper/execute_collection_command.rb +46 -0
- data/lib/api_maker/spec_helper/execute_member_command.rb +52 -0
- data/lib/api_maker/spec_helper/expect_no_browser_errors.rb +18 -0
- data/lib/api_maker/spec_helper/wait_for_expect.rb +20 -0
- data/lib/api_maker/spec_helper/wait_for_flash_message.rb +21 -0
- data/lib/api_maker/spec_helper.rb +112 -48
- data/lib/api_maker/version.rb +1 -1
- data/lib/api_maker.rb +7 -3
- metadata +108 -89
- data/README.md +0 -476
- data/app/controllers/api_maker/devise_controller.rb +0 -60
- data/lib/api_maker/base_command.rb +0 -81
- data/lib/api_maker/javascript/api.js +0 -92
- data/lib/api_maker/javascript/base-model.js +0 -543
- data/lib/api_maker/javascript/bootstrap/attribute-row.jsx +0 -16
- data/lib/api_maker/javascript/bootstrap/attribute-rows.jsx +0 -47
- data/lib/api_maker/javascript/bootstrap/card.jsx +0 -79
- data/lib/api_maker/javascript/bootstrap/checkbox.jsx +0 -127
- data/lib/api_maker/javascript/bootstrap/checkboxes.jsx +0 -105
- data/lib/api_maker/javascript/bootstrap/live-table.jsx +0 -168
- data/lib/api_maker/javascript/bootstrap/money-input.jsx +0 -136
- data/lib/api_maker/javascript/bootstrap/radio-buttons.jsx +0 -80
- data/lib/api_maker/javascript/bootstrap/select.jsx +0 -168
- data/lib/api_maker/javascript/bootstrap/string-input.jsx +0 -203
- data/lib/api_maker/javascript/cable-connection-pool.js +0 -169
- data/lib/api_maker/javascript/cable-subscription-pool.js +0 -111
- data/lib/api_maker/javascript/cable-subscription.js +0 -33
- data/lib/api_maker/javascript/collection.js +0 -186
- data/lib/api_maker/javascript/commands-pool.js +0 -123
- data/lib/api_maker/javascript/custom-error.js +0 -14
- data/lib/api_maker/javascript/deserializer.js +0 -35
- data/lib/api_maker/javascript/devise.js.erb +0 -113
- data/lib/api_maker/javascript/error-logger.js +0 -119
- data/lib/api_maker/javascript/event-connection.jsx +0 -24
- data/lib/api_maker/javascript/event-created.jsx +0 -26
- data/lib/api_maker/javascript/event-destroyed.jsx +0 -26
- data/lib/api_maker/javascript/event-emitter-listener.jsx +0 -32
- data/lib/api_maker/javascript/event-listener.jsx +0 -41
- data/lib/api_maker/javascript/event-updated.jsx +0 -26
- data/lib/api_maker/javascript/form-data-to-object.js +0 -70
- data/lib/api_maker/javascript/included.js +0 -39
- data/lib/api_maker/javascript/key-value-store.js +0 -47
- data/lib/api_maker/javascript/logger.js +0 -23
- data/lib/api_maker/javascript/model-name.js +0 -21
- data/lib/api_maker/javascript/models-response-reader.js +0 -43
- data/lib/api_maker/javascript/paginate.jsx +0 -128
- data/lib/api_maker/javascript/params.js +0 -68
- data/lib/api_maker/javascript/resource-route.jsx +0 -75
- data/lib/api_maker/javascript/resource-routes.jsx +0 -36
- data/lib/api_maker/javascript/result.js +0 -25
- data/lib/api_maker/javascript/session-status-updater.js +0 -113
- data/lib/api_maker/javascript/sort-link.jsx +0 -88
- data/lib/api_maker/javascript/updated-attribute.jsx +0 -60
- data/lib/api_maker/preloader_through.rb +0 -101
- data/lib/api_maker/relationship_includer.rb +0 -42
@@ -1,168 +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 BootstrapSelect extends React.Component {
|
8
|
-
static propTypes = PropTypesExact({
|
9
|
-
attribute: PropTypes.string,
|
10
|
-
children: PropTypes.node,
|
11
|
-
className: PropTypes.string,
|
12
|
-
"data-controller": PropTypes.string,
|
13
|
-
defaultValue: PropTypes.oneOfType([PropTypes.array, PropTypes.number, PropTypes.string]),
|
14
|
-
description: PropTypes.node,
|
15
|
-
disabled: PropTypes.bool,
|
16
|
-
id: PropTypes.string,
|
17
|
-
includeBlank: PropTypes.bool,
|
18
|
-
hideSearch: PropTypes.bool,
|
19
|
-
hint: PropTypes.node,
|
20
|
-
hintBottom: PropTypes.node,
|
21
|
-
label: PropTypes.node,
|
22
|
-
labelContainerClassName: PropTypes.string,
|
23
|
-
model: PropTypes.object,
|
24
|
-
multiple: PropTypes.bool,
|
25
|
-
name: PropTypes.string,
|
26
|
-
placeholder: PropTypes.string,
|
27
|
-
onChange: PropTypes.func,
|
28
|
-
options: PropTypes.array,
|
29
|
-
select2: PropTypes.bool,
|
30
|
-
wrapperClassName: PropTypes.string,
|
31
|
-
})
|
32
|
-
|
33
|
-
componentDidMount() {
|
34
|
-
if (this.props.select2 && this.props.onChange)
|
35
|
-
$(this.refs.select).on("change", this.props.onChange)
|
36
|
-
|
37
|
-
// Set default value to nothing when multiple
|
38
|
-
if (this.props.select2 && this.props.multiple && !this.inputDefaultValue())
|
39
|
-
$(this.refs.select).val("")
|
40
|
-
}
|
41
|
-
|
42
|
-
componentWillUnmount() {
|
43
|
-
if (this.props.select2 && this.props.onChange)
|
44
|
-
$(this.refs.select).off("change", this.props.onChange)
|
45
|
-
}
|
46
|
-
|
47
|
-
render() {
|
48
|
-
return (
|
49
|
-
<div className={this.wrapperClassName()}>
|
50
|
-
{this.label() &&
|
51
|
-
<div className={this.props.labelContainerClassName ? this.props.labelContainerClassName : null}>
|
52
|
-
<label className={this.labelClassName()} htmlFor={this.inputId()}>
|
53
|
-
{this.label()}
|
54
|
-
</label>
|
55
|
-
</div>
|
56
|
-
}
|
57
|
-
{this.props.description &&
|
58
|
-
<div className="mb-4">
|
59
|
-
{this.props.description}
|
60
|
-
</div>
|
61
|
-
}
|
62
|
-
{this.props.hint &&
|
63
|
-
<span className="form-text text-muted font-smoothing font-xs">
|
64
|
-
{this.props.hint}
|
65
|
-
</span>
|
66
|
-
}
|
67
|
-
<select
|
68
|
-
data-controller={this.dataController()}
|
69
|
-
data-hide-search={this.props.hideSearch}
|
70
|
-
data-placeholder={this.props.placeholder}
|
71
|
-
defaultValue={this.inputDefaultValue()}
|
72
|
-
className={`form-control ${this.props.className}`}
|
73
|
-
disabled={this.props.disabled}
|
74
|
-
id={this.inputId()}
|
75
|
-
multiple={this.props.multiple}
|
76
|
-
name={this.inputName()}
|
77
|
-
onChange={this.props.onChange}
|
78
|
-
ref="select"
|
79
|
-
>
|
80
|
-
{this.includeBlank() &&
|
81
|
-
<option />
|
82
|
-
}
|
83
|
-
{this.props.options && this.props.options.map(option => (
|
84
|
-
<option key={`select-option-${option[1]}`} value={option[1]}>{option[0]}</option>
|
85
|
-
))}
|
86
|
-
{this.props.children}
|
87
|
-
</select>
|
88
|
-
{this.props.hintBottom &&
|
89
|
-
<span className="form-text text-muted font-smoothing font-xs">
|
90
|
-
{this.props.hintBottom}
|
91
|
-
</span>
|
92
|
-
}
|
93
|
-
</div>
|
94
|
-
)
|
95
|
-
}
|
96
|
-
|
97
|
-
dataController() {
|
98
|
-
if ("data-controller" in this.props) {
|
99
|
-
return this.props["data-controller"]
|
100
|
-
} else if (this.props.select2) {
|
101
|
-
return "select2--default"
|
102
|
-
}
|
103
|
-
}
|
104
|
-
|
105
|
-
includeBlank() {
|
106
|
-
if (this.props.includeBlank || (this.props.placeholder && !this.props.multiple)) {
|
107
|
-
return true
|
108
|
-
} else {
|
109
|
-
return false
|
110
|
-
}
|
111
|
-
}
|
112
|
-
|
113
|
-
inputDefaultValue() {
|
114
|
-
if ("defaultValue" in this.props) {
|
115
|
-
return this.props.defaultValue
|
116
|
-
} else if (this.props.selected) {
|
117
|
-
return this.props.selected
|
118
|
-
} else if (this.props.model) {
|
119
|
-
if (!this.props.model[this.props.attribute])
|
120
|
-
throw new Error(`No attribute by that name: ${this.props.attribute}`)
|
121
|
-
|
122
|
-
return this.props.model[this.props.attribute]()
|
123
|
-
}
|
124
|
-
}
|
125
|
-
|
126
|
-
inputId() {
|
127
|
-
if ("id" in this.props) {
|
128
|
-
return this.props.id
|
129
|
-
} else if (this.props.model) {
|
130
|
-
return `${this.props.model.modelClassData().paramKey}_${inflection.underscore(this.props.attribute)}`
|
131
|
-
}
|
132
|
-
}
|
133
|
-
|
134
|
-
inputName() {
|
135
|
-
if ("name" in this.props) {
|
136
|
-
return this.props.name
|
137
|
-
} else if (this.props.model) {
|
138
|
-
return `${this.props.model.modelClassData().paramKey}[${inflection.underscore(this.props.attribute)}]`
|
139
|
-
}
|
140
|
-
}
|
141
|
-
|
142
|
-
label() {
|
143
|
-
if ("label" in this.props) {
|
144
|
-
return this.props.label
|
145
|
-
} else if (this.props.model) {
|
146
|
-
let attributeMethodName = inflection.camelize(this.props.attribute.replace(/_id$/, ""), true)
|
147
|
-
return this.props.model.modelClass().humanAttributeName(attributeMethodName)
|
148
|
-
}
|
149
|
-
}
|
150
|
-
|
151
|
-
labelClassName() {
|
152
|
-
let classNames = ["form-group-label"]
|
153
|
-
|
154
|
-
if (this.props.labelClassName)
|
155
|
-
classNames.push(this.props.labelClassName)
|
156
|
-
|
157
|
-
return classNames.join(" ")
|
158
|
-
}
|
159
|
-
|
160
|
-
wrapperClassName() {
|
161
|
-
let classNames = ["form-group", "component-bootstrap-select"]
|
162
|
-
|
163
|
-
if (this.props.wrapperClassName)
|
164
|
-
classNames.push(this.props.wrapperClassName)
|
165
|
-
|
166
|
-
return classNames.join(" ")
|
167
|
-
}
|
168
|
-
}
|
@@ -1,203 +0,0 @@
|
|
1
|
-
import MoneyInput from "./money-input"
|
2
|
-
import PropTypes from "prop-types"
|
3
|
-
import PropTypesExact from "prop-types-exact"
|
4
|
-
import React from "react"
|
5
|
-
|
6
|
-
const inflection = require("inflection")
|
7
|
-
|
8
|
-
export default class BootstrapStringInput extends React.Component {
|
9
|
-
static propTypes = PropTypesExact({
|
10
|
-
append: PropTypes.node,
|
11
|
-
attribute: PropTypes.string,
|
12
|
-
autoComplete: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),
|
13
|
-
className: PropTypes.string,
|
14
|
-
currenciesCollection: PropTypes.array,
|
15
|
-
currencyName: PropTypes.string,
|
16
|
-
"data-controller": PropTypes.string,
|
17
|
-
defaultValue: PropTypes.node,
|
18
|
-
disabled: PropTypes.bool,
|
19
|
-
hint: PropTypes.node,
|
20
|
-
hintBottom: PropTypes.node,
|
21
|
-
id: PropTypes.string,
|
22
|
-
label: PropTypes.node,
|
23
|
-
labelClassName: PropTypes.string,
|
24
|
-
maxLength: PropTypes.number,
|
25
|
-
model: PropTypes.object,
|
26
|
-
name: PropTypes.string,
|
27
|
-
onChange: PropTypes.func,
|
28
|
-
onKeyUp: PropTypes.func,
|
29
|
-
placeholder: PropTypes.node,
|
30
|
-
rows: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
31
|
-
step: PropTypes.number,
|
32
|
-
small: PropTypes.bool,
|
33
|
-
type: PropTypes.string,
|
34
|
-
wrapperClassName: PropTypes.string
|
35
|
-
})
|
36
|
-
|
37
|
-
render() {
|
38
|
-
return (
|
39
|
-
<div className={this.wrapperClassName()} ref="wrapper">
|
40
|
-
{this.label() &&
|
41
|
-
<label className={this.labelClassName()} htmlFor={this.inputId()}>
|
42
|
-
{this.label()}
|
43
|
-
</label>
|
44
|
-
}
|
45
|
-
{this.props.hint &&
|
46
|
-
<span className="form-text text-muted font-smoothing font-xs">
|
47
|
-
{this.props.hint}
|
48
|
-
</span>
|
49
|
-
}
|
50
|
-
{this.inputType() == "textarea" &&
|
51
|
-
<textarea
|
52
|
-
className={this.inputClassName()}
|
53
|
-
data-controller={this.props["data-controller"]}
|
54
|
-
defaultValue={this.inputDefaultValue()}
|
55
|
-
id={this.inputId()}
|
56
|
-
maxLength={this.props.maxLength}
|
57
|
-
name={this.inputName()}
|
58
|
-
onChange={this.props.onChange}
|
59
|
-
onKeyUp={this.props.onKeyUp}
|
60
|
-
placeholder={this.props.placeholder}
|
61
|
-
ref="input"
|
62
|
-
rows={this.props.rows}
|
63
|
-
/>
|
64
|
-
}
|
65
|
-
{this.inputType() == "money" &&
|
66
|
-
<MoneyInput
|
67
|
-
attribute={this.props.attribute}
|
68
|
-
currenciesCollection={this.props.currenciesCollection}
|
69
|
-
currencyName={this.props.currencyName}
|
70
|
-
model={this.props.model}
|
71
|
-
name={this.props.name}
|
72
|
-
className={this.inputClassName()}
|
73
|
-
onChange={this.props.onChange}
|
74
|
-
placeholder={this.props.placeholder}
|
75
|
-
small={this.props.small}
|
76
|
-
ref="money"
|
77
|
-
/>
|
78
|
-
}
|
79
|
-
{this.inputType() != "textarea" && this.inputType() != "money" &&
|
80
|
-
<div className="input-group">
|
81
|
-
{this.props.prepend &&
|
82
|
-
<div className="input-group-prepend">
|
83
|
-
<span className="input-group-text">
|
84
|
-
{this.props.prepend}
|
85
|
-
</span>
|
86
|
-
</div>
|
87
|
-
}
|
88
|
-
<input
|
89
|
-
autoComplete={this.props.autoComplete}
|
90
|
-
className={this.inputClassName()}
|
91
|
-
data-controller={this.props["data-controller"]}
|
92
|
-
defaultValue={this.inputDefaultValue()}
|
93
|
-
disabled={this.props.disabled}
|
94
|
-
id={this.inputId()}
|
95
|
-
name={this.inputName()}
|
96
|
-
onChange={this.props.onChange}
|
97
|
-
onKeyUp={this.props.onKeyUp}
|
98
|
-
placeholder={this.props.placeholder}
|
99
|
-
ref="input"
|
100
|
-
step={this.props.step}
|
101
|
-
type={this.inputType()}
|
102
|
-
/>
|
103
|
-
{this.props.append &&
|
104
|
-
<div className="input-group-append">
|
105
|
-
<span className="input-group-text">
|
106
|
-
{this.props.append}
|
107
|
-
</span>
|
108
|
-
</div>
|
109
|
-
}
|
110
|
-
</div>
|
111
|
-
}
|
112
|
-
{this.props.hintBottom &&
|
113
|
-
<span className="form-text text-muted font-smoothing font-xs">
|
114
|
-
{this.props.hintBottom}
|
115
|
-
</span>
|
116
|
-
}
|
117
|
-
</div>
|
118
|
-
)
|
119
|
-
}
|
120
|
-
|
121
|
-
inputClassName() {
|
122
|
-
var classNames = ["form-control"]
|
123
|
-
|
124
|
-
if (this.props.className)
|
125
|
-
classNames.push(this.props.className)
|
126
|
-
|
127
|
-
return classNames.join(" ")
|
128
|
-
}
|
129
|
-
|
130
|
-
inputDefaultValue() {
|
131
|
-
if ("defaultValue" in this.props) {
|
132
|
-
return this.formatValue(this.props.defaultValue)
|
133
|
-
} else if (this.props.model) {
|
134
|
-
if (!this.props.model[this.props.attribute])
|
135
|
-
throw new Error(`No such attribute: ${this.props.model.modelClassData().name}#${this.props.attribute}`)
|
136
|
-
|
137
|
-
return this.formatValue(this.props.model[this.props.attribute]())
|
138
|
-
}
|
139
|
-
}
|
140
|
-
|
141
|
-
formatValue(value) {
|
142
|
-
// We need to use a certain format for datetime-local
|
143
|
-
if (this.inputType() == "datetime-local" && value instanceof Date) {
|
144
|
-
return I18n.strftime(value, "%Y-%m-%dT%H:%M:%S")
|
145
|
-
} else if (this.inputType() == "date" && value instanceof Date) {
|
146
|
-
return I18n.strftime(value, "%Y-%m-%d")
|
147
|
-
}
|
148
|
-
|
149
|
-
return value
|
150
|
-
}
|
151
|
-
|
152
|
-
inputId() {
|
153
|
-
if ("id" in this.props) {
|
154
|
-
return this.props.id
|
155
|
-
} else if (this.props.model) {
|
156
|
-
return `${this.props.model.modelClassData().paramKey}_${inflection.underscore(this.props.attribute)}`
|
157
|
-
}
|
158
|
-
}
|
159
|
-
|
160
|
-
inputName() {
|
161
|
-
if ("name" in this.props) {
|
162
|
-
return this.props.name
|
163
|
-
} else if (this.props.model) {
|
164
|
-
return `${this.props.model.modelClassData().paramKey}[${inflection.underscore(this.props.attribute)}]`
|
165
|
-
}
|
166
|
-
}
|
167
|
-
|
168
|
-
inputType() {
|
169
|
-
if (this.props.type) {
|
170
|
-
return this.props.type
|
171
|
-
} else {
|
172
|
-
return "text"
|
173
|
-
}
|
174
|
-
}
|
175
|
-
|
176
|
-
label() {
|
177
|
-
if (this.props.label === false) {
|
178
|
-
return null
|
179
|
-
} else if (this.props.label) {
|
180
|
-
return this.props.label
|
181
|
-
} else if (this.props.model) {
|
182
|
-
return this.props.model.modelClass().humanAttributeName(this.props.attribute)
|
183
|
-
}
|
184
|
-
}
|
185
|
-
|
186
|
-
labelClassName() {
|
187
|
-
var classNames = []
|
188
|
-
|
189
|
-
if (this.props.labelClassName)
|
190
|
-
classNames.push(this.props.labelClassName)
|
191
|
-
|
192
|
-
return classNames.join(" ")
|
193
|
-
}
|
194
|
-
|
195
|
-
wrapperClassName() {
|
196
|
-
var classNames = ["form-group", "component-bootstrap-string-input"]
|
197
|
-
|
198
|
-
if (this.props.wrapperClassName)
|
199
|
-
classNames.push(this.props.wrapperClassName)
|
200
|
-
|
201
|
-
return classNames.join(" ")
|
202
|
-
}
|
203
|
-
}
|
@@ -1,169 +0,0 @@
|
|
1
|
-
import CableSubscriptionPool from "./cable-subscription-pool"
|
2
|
-
import CableSubscription from "./cable-subscription"
|
3
|
-
|
4
|
-
export default class ApiMakerCableConnectionPool {
|
5
|
-
static current() {
|
6
|
-
if (!window.apiMakerCableConnectionPool)
|
7
|
-
window.apiMakerCableConnectionPool = new ApiMakerCableConnectionPool()
|
8
|
-
|
9
|
-
return window.apiMakerCableConnectionPool
|
10
|
-
}
|
11
|
-
|
12
|
-
constructor() {
|
13
|
-
this.connections = {}
|
14
|
-
this.upcomingSubscriptionData = {}
|
15
|
-
this.upcomingSubscriptions = []
|
16
|
-
}
|
17
|
-
|
18
|
-
connectCreated(modelName, callback) {
|
19
|
-
if (!this.upcomingSubscriptionData[modelName])
|
20
|
-
this.upcomingSubscriptionData[modelName] = {}
|
21
|
-
|
22
|
-
if (!this.upcomingSubscriptionData[modelName]["creates"])
|
23
|
-
this.upcomingSubscriptionData[modelName]["creates"] = true
|
24
|
-
|
25
|
-
if (!this.upcomingSubscriptions[modelName])
|
26
|
-
this.upcomingSubscriptions[modelName] = {}
|
27
|
-
|
28
|
-
if (!this.upcomingSubscriptions[modelName]["creates"])
|
29
|
-
this.upcomingSubscriptions[modelName]["creates"] = []
|
30
|
-
|
31
|
-
var subscription = new CableSubscription({
|
32
|
-
callback: callback,
|
33
|
-
modelName: modelName
|
34
|
-
})
|
35
|
-
|
36
|
-
this.upcomingSubscriptions[modelName]["creates"].push(subscription)
|
37
|
-
|
38
|
-
this.scheduleConnectUpcoming()
|
39
|
-
|
40
|
-
return subscription
|
41
|
-
}
|
42
|
-
|
43
|
-
connectDestroyed(modelName, modelId, callback) {
|
44
|
-
if (!this.upcomingSubscriptionData[modelName])
|
45
|
-
this.upcomingSubscriptionData[modelName] = {}
|
46
|
-
|
47
|
-
if (!this.upcomingSubscriptionData[modelName]["destroys"])
|
48
|
-
this.upcomingSubscriptionData[modelName]["destroys"] = []
|
49
|
-
|
50
|
-
if (!this.upcomingSubscriptionData[modelName]["destroys"].includes(modelId))
|
51
|
-
this.upcomingSubscriptionData[modelName]["destroys"].push(modelId)
|
52
|
-
|
53
|
-
if (!this.upcomingSubscriptions[modelName])
|
54
|
-
this.upcomingSubscriptions[modelName] = {}
|
55
|
-
|
56
|
-
if (!this.upcomingSubscriptions[modelName]["destroys"])
|
57
|
-
this.upcomingSubscriptions[modelName]["destroys"] = {}
|
58
|
-
|
59
|
-
if (!this.upcomingSubscriptions[modelName]["destroys"][modelId])
|
60
|
-
this.upcomingSubscriptions[modelName]["destroys"][modelId] = []
|
61
|
-
|
62
|
-
var subscription = new CableSubscription({
|
63
|
-
callback: callback,
|
64
|
-
modelName: modelName,
|
65
|
-
modelId: modelId
|
66
|
-
})
|
67
|
-
|
68
|
-
this.upcomingSubscriptions[modelName]["destroys"][modelId].push(subscription)
|
69
|
-
|
70
|
-
this.scheduleConnectUpcoming()
|
71
|
-
|
72
|
-
return subscription
|
73
|
-
}
|
74
|
-
|
75
|
-
connectEvent(modelName, modelId, eventName, callback) {
|
76
|
-
if (!this.upcomingSubscriptionData[modelName])
|
77
|
-
this.upcomingSubscriptionData[modelName] = {}
|
78
|
-
|
79
|
-
if (!this.upcomingSubscriptionData[modelName]["events"])
|
80
|
-
this.upcomingSubscriptionData[modelName]["events"] = {}
|
81
|
-
|
82
|
-
if (!this.upcomingSubscriptionData[modelName]["events"][eventName])
|
83
|
-
this.upcomingSubscriptionData[modelName]["events"][eventName] = []
|
84
|
-
|
85
|
-
if (!this.upcomingSubscriptionData[modelName]["events"][eventName].includes(modelId))
|
86
|
-
this.upcomingSubscriptionData[modelName]["events"][eventName].push(modelId)
|
87
|
-
|
88
|
-
if (!this.upcomingSubscriptions[modelName])
|
89
|
-
this.upcomingSubscriptions[modelName] = {}
|
90
|
-
|
91
|
-
if (!this.upcomingSubscriptions[modelName]["events"])
|
92
|
-
this.upcomingSubscriptions[modelName]["events"] = {}
|
93
|
-
|
94
|
-
if (!this.upcomingSubscriptions[modelName]["events"])
|
95
|
-
this.upcomingSubscriptions[modelName]["events"] = {}
|
96
|
-
|
97
|
-
if (!this.upcomingSubscriptions[modelName]["events"][modelId])
|
98
|
-
this.upcomingSubscriptions[modelName]["events"][modelId] = {}
|
99
|
-
|
100
|
-
if (!this.upcomingSubscriptions[modelName]["events"][modelId][eventName])
|
101
|
-
this.upcomingSubscriptions[modelName]["events"][modelId][eventName] = []
|
102
|
-
|
103
|
-
var subscription = new CableSubscription({
|
104
|
-
callback: callback,
|
105
|
-
modelName: modelName,
|
106
|
-
modelId: modelId
|
107
|
-
})
|
108
|
-
|
109
|
-
this.upcomingSubscriptions[modelName]["events"][modelId][eventName].push(subscription)
|
110
|
-
|
111
|
-
this.scheduleConnectUpcoming()
|
112
|
-
|
113
|
-
return subscription
|
114
|
-
}
|
115
|
-
|
116
|
-
connectUpdate(modelName, modelId, callback) {
|
117
|
-
if (!this.upcomingSubscriptionData[modelName])
|
118
|
-
this.upcomingSubscriptionData[modelName] = {}
|
119
|
-
|
120
|
-
if (!this.upcomingSubscriptionData[modelName]["updates"])
|
121
|
-
this.upcomingSubscriptionData[modelName]["updates"] = []
|
122
|
-
|
123
|
-
if (!this.upcomingSubscriptionData[modelName]["updates"].includes(modelId))
|
124
|
-
this.upcomingSubscriptionData[modelName]["updates"].push(modelId)
|
125
|
-
|
126
|
-
if (!this.upcomingSubscriptions[modelName])
|
127
|
-
this.upcomingSubscriptions[modelName] = {}
|
128
|
-
|
129
|
-
if (!this.upcomingSubscriptions[modelName]["updates"])
|
130
|
-
this.upcomingSubscriptions[modelName]["updates"] = {}
|
131
|
-
|
132
|
-
if (!this.upcomingSubscriptions[modelName]["updates"][modelId])
|
133
|
-
this.upcomingSubscriptions[modelName]["updates"][modelId] = []
|
134
|
-
|
135
|
-
var subscription = new CableSubscription({
|
136
|
-
callback: callback,
|
137
|
-
modelName: modelName,
|
138
|
-
modelId: modelId
|
139
|
-
})
|
140
|
-
|
141
|
-
this.upcomingSubscriptions[modelName]["updates"][modelId].push(subscription)
|
142
|
-
|
143
|
-
this.scheduleConnectUpcoming()
|
144
|
-
|
145
|
-
return subscription
|
146
|
-
}
|
147
|
-
|
148
|
-
connectUpcoming() {
|
149
|
-
var subscriptionData = this.upcomingSubscriptionData
|
150
|
-
var subscriptions = this.upcomingSubscriptions
|
151
|
-
|
152
|
-
this.upcomingSubscriptionData = {}
|
153
|
-
this.upcomingSubscriptions = {}
|
154
|
-
|
155
|
-
var cableSubscriptionPool = new CableSubscriptionPool({
|
156
|
-
subscriptionData: subscriptionData,
|
157
|
-
subscriptions: subscriptions
|
158
|
-
})
|
159
|
-
|
160
|
-
return cableSubscriptionPool
|
161
|
-
}
|
162
|
-
|
163
|
-
scheduleConnectUpcoming() {
|
164
|
-
if (this.scheduleConnectUpcomingTimeout)
|
165
|
-
clearTimeout(this.scheduleConnectUpcomingTimeout)
|
166
|
-
|
167
|
-
this.scheduleConnectUpcomingTimeout = setTimeout(() => this.connectUpcoming(), 50)
|
168
|
-
}
|
169
|
-
}
|
@@ -1,111 +0,0 @@
|
|
1
|
-
import CommandsPool from "./commands-pool"
|
2
|
-
import Deserializer from "./deserializer"
|
3
|
-
import Logger from "./logger"
|
4
|
-
|
5
|
-
const inflection = require("inflection")
|
6
|
-
|
7
|
-
export default class ApiMakerCableSubscriptionPool {
|
8
|
-
constructor(props) {
|
9
|
-
this.props = props
|
10
|
-
this.activeSubscriptions = 0
|
11
|
-
this.registerSubscriptions()
|
12
|
-
this.connect()
|
13
|
-
}
|
14
|
-
|
15
|
-
connect() {
|
16
|
-
var globalData = CommandsPool.current().globalRequestData
|
17
|
-
|
18
|
-
this.subscription = App.cable.subscriptions.create(
|
19
|
-
{channel: "ApiMaker::SubscriptionsChannel", global: globalData, subscription_data: this.props.subscriptionData},
|
20
|
-
{received: (data) => this.onReceived(data)}
|
21
|
-
)
|
22
|
-
}
|
23
|
-
|
24
|
-
onReceived(rawData) {
|
25
|
-
var data = Deserializer.parse(rawData)
|
26
|
-
var modelType = data.model_type
|
27
|
-
var modelName = inflection.camelize(inflection.singularize(modelType.replace(/-/g, "_")))
|
28
|
-
var modelId = data.model_id
|
29
|
-
var modelInstance = data.model
|
30
|
-
var subscriptions = this.props.subscriptions
|
31
|
-
|
32
|
-
if (data.type == "update") {
|
33
|
-
for(var subscription of subscriptions[modelName]["updates"][modelId]) {
|
34
|
-
subscription.onReceived({model: modelInstance})
|
35
|
-
}
|
36
|
-
} else if (data.type == "create") {
|
37
|
-
for(var subscription of subscriptions[modelName]["creates"]) {
|
38
|
-
subscription.onReceived({model: modelInstance})
|
39
|
-
}
|
40
|
-
} else if (data.type == "destroy") {
|
41
|
-
for(var subscription of subscriptions[modelName]["destroys"][modelId]) {
|
42
|
-
subscription.onReceived({model: modelInstance})
|
43
|
-
}
|
44
|
-
} else if (data.type == "event") {
|
45
|
-
for(var subscription of subscriptions[modelName]["events"][modelId][data.event_name]) {
|
46
|
-
subscription.onReceived({
|
47
|
-
args: data.args,
|
48
|
-
eventName: data.event_name,
|
49
|
-
model: modelInstance
|
50
|
-
})
|
51
|
-
}
|
52
|
-
} else {
|
53
|
-
throw new Error(`Unknown type: ${data.type}`)
|
54
|
-
}
|
55
|
-
}
|
56
|
-
|
57
|
-
onUnsubscribe() {
|
58
|
-
Logger.log(`activeSubscriptions before unsub: ${this.activeSubscriptions}`)
|
59
|
-
this.activeSubscriptions -= 1
|
60
|
-
Logger.log(`activeSubscriptions after unsub: ${this.activeSubscriptions}`)
|
61
|
-
|
62
|
-
if (this.activeSubscriptions <= 0) {
|
63
|
-
Logger.log("Unsubscribe from ActionCable subscription")
|
64
|
-
this.subscription.unsubscribe()
|
65
|
-
}
|
66
|
-
}
|
67
|
-
|
68
|
-
registerSubscriptions() {
|
69
|
-
Logger.log(`registerSubscriptions: ${this.props.subscriptions.length}`)
|
70
|
-
Logger.log(this.props.subscriptions)
|
71
|
-
|
72
|
-
for(var modelName in this.props.subscriptions) {
|
73
|
-
if (this.props.subscriptions[modelName]["creates"]) {
|
74
|
-
for(var subscription of this.props.subscriptions[modelName]["creates"]) {
|
75
|
-
this.connectUnsubscriptionForSubscription(subscription)
|
76
|
-
}
|
77
|
-
}
|
78
|
-
|
79
|
-
if (this.props.subscriptions[modelName]["events"]) {
|
80
|
-
for(var eventName in this.props.subscriptions[modelName]["events"]) {
|
81
|
-
for(var modelId in this.props.subscriptions[modelName]["events"][eventName]) {
|
82
|
-
for(var subscription of this.props.subscriptions[modelName]["events"][eventName][modelId]) {
|
83
|
-
this.connectUnsubscriptionForSubscription(subscription)
|
84
|
-
}
|
85
|
-
}
|
86
|
-
}
|
87
|
-
}
|
88
|
-
|
89
|
-
if (this.props.subscriptions[modelName]["updates"]) {
|
90
|
-
for(var modelId in this.props.subscriptions[modelName]["updates"]) {
|
91
|
-
for(var subscription of this.props.subscriptions[modelName]["updates"][modelId]) {
|
92
|
-
this.connectUnsubscriptionForSubscription(subscription)
|
93
|
-
}
|
94
|
-
}
|
95
|
-
}
|
96
|
-
}
|
97
|
-
}
|
98
|
-
|
99
|
-
connectUnsubscriptionForSubscription(subscription) {
|
100
|
-
Logger.log("Connecting to unsubscribe on subscription")
|
101
|
-
Logger.log({ subscription })
|
102
|
-
|
103
|
-
this.activeSubscriptions += 1
|
104
|
-
|
105
|
-
subscription.onUnsubscribe(() => {
|
106
|
-
Logger.log("Call onUnsubscribe on self")
|
107
|
-
|
108
|
-
this.onUnsubscribe(subscription)
|
109
|
-
})
|
110
|
-
}
|
111
|
-
}
|
@@ -1,33 +0,0 @@
|
|
1
|
-
import Logger from "./logger"
|
2
|
-
|
3
|
-
export default class ApiMakerCableSubscription {
|
4
|
-
constructor(props) {
|
5
|
-
this.props = props
|
6
|
-
this.onUnsubscribeCallbacks = []
|
7
|
-
this.subscribed = true
|
8
|
-
}
|
9
|
-
|
10
|
-
onReceived(data) {
|
11
|
-
this.props.callback.apply(null, [data])
|
12
|
-
}
|
13
|
-
|
14
|
-
onUnsubscribe(callback) {
|
15
|
-
this.onUnsubscribeCallbacks.push(callback)
|
16
|
-
}
|
17
|
-
|
18
|
-
unsubscribe() {
|
19
|
-
if (!this.subscribed) {
|
20
|
-
Logger.log("Unsubscribed already called")
|
21
|
-
return
|
22
|
-
}
|
23
|
-
|
24
|
-
Logger.log(`Unsubscribe called: ${this.onUnsubscribeCallbacks.length}`)
|
25
|
-
|
26
|
-
for(var onUnsubscribeCallback of this.onUnsubscribeCallbacks) {
|
27
|
-
Logger.log("onUnsubscribe called for a callback")
|
28
|
-
onUnsubscribeCallback.call()
|
29
|
-
}
|
30
|
-
|
31
|
-
this.subscribed = false
|
32
|
-
}
|
33
|
-
}
|