avo 2.10.2 → 2.11.1.pre.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of avo might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Gemfile.lock +64 -62
- data/app/components/avo/fields/country_field/edit_component.html.erb +9 -3
- data/app/components/avo/fields/date_field/edit_component.html.erb +26 -8
- data/app/components/avo/fields/date_field/index_component.html.erb +7 -1
- data/app/components/avo/fields/date_field/show_component.html.erb +7 -1
- data/app/components/avo/fields/date_time_field/edit_component.html.erb +26 -10
- data/app/components/avo/fields/date_time_field/index_component.html.erb +10 -1
- data/app/components/avo/fields/date_time_field/show_component.html.erb +10 -1
- data/app/components/avo/fields/file_field/edit_component.html.erb +1 -0
- data/app/components/avo/fields/files_field/edit_component.html.erb +1 -0
- data/app/components/avo/fields/select_field/edit_component.html.erb +14 -10
- data/app/components/avo/index/ordering/button_component.rb +1 -5
- data/app/components/avo/views/resource_index_component.html.erb +1 -1
- data/app/controllers/avo/application_controller.rb +15 -9
- data/app/controllers/avo/base_controller.rb +11 -3
- data/app/controllers/avo/reorder_controller.rb +25 -0
- data/app/helpers/avo/application_helper.rb +6 -0
- data/app/helpers/avo/url_helpers.rb +0 -4
- data/app/javascript/js/controllers/fields/date_field_controller.js +108 -24
- data/app/javascript/js/controllers/search_controller.js +3 -0
- data/app/views/avo/partials/_javascript.html.erb +1 -1
- data/config/routes.rb +5 -4
- data/db/factories.rb +1 -0
- data/lib/avo/app.rb +1 -3
- data/lib/avo/base_action.rb +8 -6
- data/lib/avo/base_resource.rb +7 -8
- data/lib/avo/concerns/handles_field_args.rb +1 -1
- data/lib/avo/concerns/has_fields.rb +2 -0
- data/lib/avo/configuration.rb +2 -12
- data/lib/avo/fields/base_field.rb +2 -0
- data/lib/avo/fields/country_field.rb +2 -0
- data/lib/avo/fields/date_field.rb +12 -10
- data/lib/avo/fields/date_time_field.rb +21 -9
- data/lib/avo/fields/field_extensions/has_include_blank.rb +17 -0
- data/lib/avo/fields/file_field.rb +2 -0
- data/lib/avo/fields/files_field.rb +2 -0
- data/lib/avo/fields/select_field.rb +2 -0
- data/lib/avo/licensing/h_q.rb +2 -0
- data/lib/avo/services/uri_service.rb +4 -0
- data/lib/avo/version.rb +1 -1
- data/lib/generators/avo/action_generator.rb +3 -2
- data/lib/generators/avo/base_generator.rb +14 -0
- data/lib/generators/avo/card/chartkick_generator.rb +18 -0
- data/lib/generators/avo/card/metric_generator.rb +18 -0
- data/lib/generators/avo/card/partial_generator.rb +19 -0
- data/lib/generators/avo/controller_generator.rb +9 -3
- data/lib/generators/avo/dashboard_generator.rb +2 -2
- data/lib/generators/avo/eject_generator.rb +2 -3
- data/lib/generators/avo/field_generator.rb +2 -2
- data/lib/generators/avo/filter_generator.rb +3 -2
- data/lib/generators/avo/install_generator.rb +2 -2
- data/lib/generators/avo/locales_generator.rb +2 -2
- data/lib/generators/avo/named_base_generator.rb +14 -0
- data/lib/generators/avo/resource_generator.rb +2 -2
- data/lib/generators/avo/resource_tool_generator.rb +4 -4
- data/lib/generators/avo/tool_generator.rb +4 -4
- data/lib/generators/avo/version_generator.rb +23 -0
- data/public/avo-assets/avo.css +4 -0
- data/public/avo-assets/avo.js +69 -69
- data/public/avo-assets/avo.js.map +2 -2
- metadata +12 -12
- data/db/migrate/20210421064037_add_color_to_teams.rb +0 -5
- data/db/migrate/20210423075924_add_progress_to_projects.rb +0 -5
- data/db/migrate/20210525143134_add_slug_to_users.rb +0 -6
- data/lib/avo/fields/currency_field.rb +0 -15
- data/lib/avo/has_context.rb +0 -7
- data/lib/generators/avo/chartkick_card_generator.rb +0 -16
- data/lib/generators/avo/metric_card_generator.rb +0 -16
- data/lib/generators/avo/partial_card_generator.rb +0 -17
@@ -2,63 +2,147 @@ import { Controller } from '@hotwired/stimulus'
|
|
2
2
|
import { DateTime } from 'luxon'
|
3
3
|
import flatpickr from 'flatpickr'
|
4
4
|
|
5
|
-
import { castBoolean } from '../../helpers/cast_boolean'
|
6
|
-
|
7
5
|
// Get the DateTime with the TZ offset applied.
|
8
6
|
function universalTimestamp(timestampStr) {
|
9
7
|
return new Date(new Date(timestampStr).getTime() + (new Date(timestampStr).getTimezoneOffset() * 60 * 1000))
|
10
8
|
}
|
11
9
|
|
12
10
|
export default class extends Controller {
|
13
|
-
static targets = ['input']
|
11
|
+
static targets = ['input', 'fakeInput']
|
12
|
+
|
13
|
+
static values = {
|
14
|
+
view: String,
|
15
|
+
timezone: String,
|
16
|
+
format: String,
|
17
|
+
enableTime: Boolean,
|
18
|
+
pickerFormat: String,
|
19
|
+
firstDayOfWeek: Number,
|
20
|
+
time24Hr: Boolean,
|
21
|
+
disableMobile: Boolean,
|
22
|
+
}
|
23
|
+
|
24
|
+
get browserZone() {
|
25
|
+
const time = DateTime.local()
|
26
|
+
|
27
|
+
return time.zoneName
|
28
|
+
}
|
29
|
+
|
30
|
+
get initialValue() {
|
31
|
+
if (this.isOnShow || this.isOnIndex) {
|
32
|
+
return this.context.element.innerText
|
33
|
+
} if (this.isOnEdit) {
|
34
|
+
return this.inputTarget.value
|
35
|
+
}
|
36
|
+
|
37
|
+
return null
|
38
|
+
}
|
39
|
+
|
40
|
+
get isOnIndex() {
|
41
|
+
return this.viewValue === 'index'
|
42
|
+
}
|
43
|
+
|
44
|
+
get isOnEdit() {
|
45
|
+
return this.viewValue === 'edit'
|
46
|
+
}
|
47
|
+
|
48
|
+
get isOnShow() {
|
49
|
+
return this.viewValue === 'show'
|
50
|
+
}
|
51
|
+
|
52
|
+
// Parse the time as if it were UTC
|
53
|
+
get parsedValue() {
|
54
|
+
return DateTime.fromISO(this.initialValue, { zone: 'UTC' })
|
55
|
+
}
|
56
|
+
|
57
|
+
get displayTimezone() {
|
58
|
+
return this.timezoneValue || this.browserZone
|
59
|
+
}
|
14
60
|
|
15
61
|
connect() {
|
62
|
+
if (this.isOnShow || this.isOnIndex) {
|
63
|
+
this.initShow()
|
64
|
+
} else if (this.isOnEdit) {
|
65
|
+
this.initEdit()
|
66
|
+
}
|
67
|
+
}
|
68
|
+
|
69
|
+
// Turns the value in the controller wrapper into the timezone of the browser
|
70
|
+
initShow() {
|
71
|
+
let value = this.parsedValue
|
72
|
+
|
73
|
+
// Set the zone only if the type of field is date time.
|
74
|
+
if (this.enableTimeValue) {
|
75
|
+
value = value.setZone(this.displayTimezone)
|
76
|
+
}
|
77
|
+
|
78
|
+
this.context.element.innerText = value.toFormat(this.formatValue)
|
79
|
+
}
|
80
|
+
|
81
|
+
initEdit() {
|
16
82
|
const options = {
|
17
83
|
enableTime: false,
|
18
84
|
enableSeconds: false,
|
19
85
|
// eslint-disable-next-line camelcase
|
20
|
-
time_24hr:
|
86
|
+
time_24hr: this.time24HrValue,
|
21
87
|
locale: {
|
22
88
|
firstDayOfWeek: 0,
|
23
89
|
},
|
24
90
|
altInput: true,
|
91
|
+
onChange: this.onChange.bind(this),
|
25
92
|
}
|
26
|
-
const enableTime = castBoolean(this.inputTarget.dataset.enableTime)
|
27
93
|
|
28
94
|
// Set the format of the displayed input field.
|
29
|
-
options.altFormat = this.
|
95
|
+
options.altFormat = this.pickerFormatValue
|
30
96
|
|
31
97
|
// Disable native input in mobile browsers
|
32
|
-
options.disableMobile = this.
|
98
|
+
options.disableMobile = this.disableMobileValue
|
33
99
|
|
34
100
|
// Set first day of the week.
|
35
|
-
options.locale.firstDayOfWeek = this.
|
101
|
+
options.locale.firstDayOfWeek = this.firstDayOfWeekValue
|
36
102
|
|
37
103
|
// Enable time if needed.
|
38
|
-
options.enableTime =
|
39
|
-
options.enableSeconds =
|
40
|
-
|
41
|
-
let currentValue
|
104
|
+
options.enableTime = this.enableTimeValue
|
105
|
+
options.enableSeconds = this.enableTimeValue
|
42
106
|
|
43
107
|
// enable timezone display
|
44
|
-
if (
|
45
|
-
|
46
|
-
|
47
|
-
currentValue = currentValue.toISO()
|
108
|
+
if (this.enableTimeValue) {
|
109
|
+
console.log(1)
|
110
|
+
options.defaultDate = this.parsedValue.setZone(this.displayTimezone).toISO()
|
48
111
|
|
49
112
|
options.dateFormat = 'Y-m-d H:i:S'
|
50
|
-
// eslint-disable-next-line camelcase
|
51
|
-
options.time_24hr = castBoolean(this.inputTarget.dataset.time24hr)
|
52
|
-
// this.timezone = Intl.DateTimeFormat().resolvedOptions().timeZone
|
53
|
-
options.appTimezone = this.inputTarget.dataset.timezone
|
54
113
|
} else {
|
55
|
-
|
114
|
+
console.log(2)
|
115
|
+
|
116
|
+
// Because the browser treats the date like a timestamp and updates it at 00:00 hour, when on a western timezone the date will be converted with one day offset.
|
56
117
|
// Ex: 2022-01-30 will render as 2022-01-29 on an American timezone
|
57
|
-
|
118
|
+
options.defaultDate = universalTimestamp(this.initialValue)
|
58
119
|
}
|
59
120
|
|
60
|
-
|
121
|
+
flatpickr(this.fakeInputTarget, options)
|
122
|
+
|
123
|
+
this.updateRealInput(this.parsedValue.setZone(this.displayTimezone).toISO())
|
124
|
+
}
|
125
|
+
|
126
|
+
onChange(selectedDates) {
|
127
|
+
let time
|
128
|
+
let args = {}
|
129
|
+
|
130
|
+
if (this.timezoneValue) {
|
131
|
+
args = { keepLocalTime: true }
|
132
|
+
} else {
|
133
|
+
args = { keepLocalTime: false }
|
134
|
+
}
|
135
|
+
|
136
|
+
if (this.enableTimeValue) {
|
137
|
+
time = DateTime.fromISO(selectedDates[0].toISOString()).setZone('UTC', args)
|
138
|
+
} else {
|
139
|
+
time = DateTime.fromISO(selectedDates[0].toISOString()).setZone('UTC', { keepLocalTime: true })
|
140
|
+
}
|
141
|
+
|
142
|
+
this.updateRealInput(time)
|
143
|
+
}
|
61
144
|
|
62
|
-
|
145
|
+
updateRealInput(value) {
|
146
|
+
this.inputTarget.value = value
|
63
147
|
}
|
64
148
|
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<%= javascript_tag nonce: true do %>
|
2
2
|
window.Avo = window.Avo || { configuration: {} }
|
3
3
|
Avo.configuration.timezone = '<%= Avo.configuration.timezone %>'
|
4
|
-
Avo.configuration.root_path = '<%=
|
4
|
+
Avo.configuration.root_path = '<%= root_path_without_url %>'
|
5
5
|
Avo.configuration.search_debounce = '<%= Avo.configuration.search_debounce %>'
|
6
6
|
<% end %>
|
data/config/routes.rb
CHANGED
@@ -16,16 +16,17 @@ Avo::Engine.routes.draw do
|
|
16
16
|
post "/resources/:resource_name/:id/attachments/", to: "attachments#create"
|
17
17
|
end
|
18
18
|
|
19
|
+
# Records ordering
|
20
|
+
scope "reorder", as: "reorder" do
|
21
|
+
patch "/:resource_name/:id", to: "reorder#order", as: "order"
|
22
|
+
end
|
23
|
+
|
19
24
|
get "failed_to_load", to: "home#failed_to_load"
|
20
25
|
|
21
26
|
scope "resources", as: "resources" do
|
22
27
|
# Attachments
|
23
28
|
delete "/:resource_name/:id/active_storage_attachments/:attachment_name/:attachment_id", to: "attachments#destroy"
|
24
29
|
|
25
|
-
# Ordering
|
26
|
-
patch "/:resource_name/:id/order", to: "resources#order", as: "order"
|
27
|
-
patch "/:resource_name/:id/:related_name/:related_id/order", to: "associations#order", as: "associations_order"
|
28
|
-
|
29
30
|
# Actions
|
30
31
|
get "/:resource_name(/:id)/actions/:action_id", to: "actions#show"
|
31
32
|
post "/:resource_name(/:id)/actions/:action_id", to: "actions#handle"
|
data/db/factories.rb
CHANGED
data/lib/avo/app.rb
CHANGED
@@ -20,8 +20,6 @@ module Avo
|
|
20
20
|
def boot
|
21
21
|
init_fields
|
22
22
|
|
23
|
-
I18n.locale = Avo.configuration.language_code
|
24
|
-
|
25
23
|
if Rails.cache.instance_of?(ActiveSupport::Cache::NullStore)
|
26
24
|
self.cache_store ||= ActiveSupport::Cache::MemoryStore.new
|
27
25
|
else
|
@@ -172,7 +170,7 @@ module Avo
|
|
172
170
|
payload[:license_abilities] = Avo::App&.license&.abilities
|
173
171
|
payload[:cache_store] = self.cache_store&.class&.to_s
|
174
172
|
payload[:avo_metadata] = hq&.avo_metadata
|
175
|
-
payload[:app_timezone] = Time.
|
173
|
+
payload[:app_timezone] = Time.current.zone
|
176
174
|
payload[:cache_key] = Avo::Licensing::HQ.cache_key
|
177
175
|
payload[:cache_key_contents] = hq&.cached_response
|
178
176
|
|
data/lib/avo/base_action.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
module Avo
|
2
2
|
class BaseAction
|
3
|
-
extend HasContext
|
4
|
-
|
5
3
|
include Avo::Concerns::HasFields
|
6
4
|
|
7
5
|
class_attribute :name, default: nil
|
@@ -23,8 +21,16 @@ module Avo
|
|
23
21
|
attr_accessor :user
|
24
22
|
|
25
23
|
delegate :view, to: :class
|
24
|
+
delegate :context, to: ::Avo::App
|
25
|
+
delegate :current_user, to: ::Avo::App
|
26
|
+
delegate :params, to: ::Avo::App
|
27
|
+
delegate :view_context, to: ::Avo::App
|
28
|
+
delegate :avo, to: :view_context
|
29
|
+
delegate :main_app, to: :view_context
|
26
30
|
|
27
31
|
class << self
|
32
|
+
delegate :context, to: ::Avo::App
|
33
|
+
|
28
34
|
def form_data_attributes
|
29
35
|
# We can't respond with a file download from Turbo se we disable it on the form
|
30
36
|
if may_download_file
|
@@ -64,10 +70,6 @@ module Avo
|
|
64
70
|
@response[:messages] = []
|
65
71
|
end
|
66
72
|
|
67
|
-
def context
|
68
|
-
self.class.context
|
69
|
-
end
|
70
|
-
|
71
73
|
def get_attributes_for_action
|
72
74
|
get_fields.map do |field|
|
73
75
|
[field.id, field.value]
|
data/lib/avo/base_resource.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
module Avo
|
2
2
|
class BaseResource
|
3
3
|
extend ActiveSupport::DescendantsTracker
|
4
|
-
extend HasContext
|
5
4
|
|
6
5
|
include ActionView::Helpers::UrlHelper
|
7
6
|
include Avo::Concerns::HasModel
|
@@ -10,12 +9,15 @@ module Avo
|
|
10
9
|
include Avo::Concerns::ModelClassConstantized
|
11
10
|
|
12
11
|
delegate :view_context, to: ::Avo::App
|
12
|
+
delegate :current_user, to: ::Avo::App
|
13
|
+
delegate :params, to: ::Avo::App
|
13
14
|
delegate :simple_format, :content_tag, to: :view_context
|
14
15
|
delegate :main_app, to: :view_context
|
15
16
|
delegate :avo, to: :view_context
|
16
17
|
delegate :resource_path, to: :view_context
|
17
18
|
delegate :resources_path, to: :view_context
|
18
19
|
delegate :t, to: ::I18n
|
20
|
+
delegate :context, to: ::Avo::App
|
19
21
|
|
20
22
|
attr_accessor :view
|
21
23
|
attr_accessor :model
|
@@ -48,6 +50,7 @@ module Avo
|
|
48
50
|
|
49
51
|
class << self
|
50
52
|
delegate :t, to: ::I18n
|
53
|
+
delegate :context, to: ::Avo::App
|
51
54
|
|
52
55
|
def grid(&block)
|
53
56
|
grid_collector = GridCollector.new
|
@@ -101,7 +104,7 @@ module Avo
|
|
101
104
|
|
102
105
|
def initialize
|
103
106
|
unless self.class.model_class.present?
|
104
|
-
if model_class.present?
|
107
|
+
if model_class.present? && model_class.respond_to?(:base_class)
|
105
108
|
self.class.model_class = model_class.base_class
|
106
109
|
end
|
107
110
|
end
|
@@ -153,7 +156,7 @@ module Avo
|
|
153
156
|
end
|
154
157
|
|
155
158
|
def class_name_without_resource
|
156
|
-
self.class.name.demodulize.
|
159
|
+
self.class.name.demodulize.delete_suffix("Resource")
|
157
160
|
end
|
158
161
|
|
159
162
|
def model_class
|
@@ -199,7 +202,7 @@ module Avo
|
|
199
202
|
end
|
200
203
|
|
201
204
|
def name
|
202
|
-
default = class_name_without_resource.
|
205
|
+
default = class_name_without_resource.to_s.gsub('::', ' ').underscore.humanize
|
203
206
|
|
204
207
|
return @name if @name.present?
|
205
208
|
|
@@ -242,10 +245,6 @@ module Avo
|
|
242
245
|
view_types
|
243
246
|
end
|
244
247
|
|
245
|
-
def context
|
246
|
-
self.class.context
|
247
|
-
end
|
248
|
-
|
249
248
|
def attached_file_fields
|
250
249
|
get_field_definitions.select do |field|
|
251
250
|
[Avo::Fields::FileField, Avo::Fields::FilesField].include? field.class
|
@@ -28,7 +28,7 @@ module Avo
|
|
28
28
|
add_prop_from_args args, name: name, default: default, type: :array
|
29
29
|
end
|
30
30
|
|
31
|
-
def add_string_prop(args, name, default =
|
31
|
+
def add_string_prop(args, name, default = nil)
|
32
32
|
add_prop_from_args args, name: name, default: default, type: :string
|
33
33
|
end
|
34
34
|
end
|
@@ -183,6 +183,7 @@ module Avo
|
|
183
183
|
if field.is_a?(Avo::Fields::BelongsToField)
|
184
184
|
if field.respond_to?(:foreign_key) &&
|
185
185
|
reflection.inverse_of.present? &&
|
186
|
+
reflection.inverse_of.respond_to?(:foreign_key) &&
|
186
187
|
reflection.inverse_of.foreign_key == field.foreign_key
|
187
188
|
is_valid = false
|
188
189
|
end
|
@@ -191,6 +192,7 @@ module Avo
|
|
191
192
|
if field.respond_to?(:foreign_key) &&
|
192
193
|
field.is_polymorphic? &&
|
193
194
|
reflection.respond_to?(:polymorphic?) &&
|
195
|
+
reflection.inverse_of.respond_to?(:foreign_key) &&
|
194
196
|
reflection.inverse_of.foreign_key == field.reflection.foreign_key
|
195
197
|
is_valid = false
|
196
198
|
end
|
data/lib/avo/configuration.rb
CHANGED
@@ -40,7 +40,7 @@ module Avo
|
|
40
40
|
@per_page = 24
|
41
41
|
@per_page_steps = [12, 24, 48, 72]
|
42
42
|
@via_per_page = 8
|
43
|
-
@locale =
|
43
|
+
@locale = nil
|
44
44
|
@currency = "USD"
|
45
45
|
@default_view_type = :table
|
46
46
|
@license = "community"
|
@@ -78,16 +78,6 @@ module Avo
|
|
78
78
|
@profile_menu = nil
|
79
79
|
end
|
80
80
|
|
81
|
-
def locale_tag
|
82
|
-
::ISO::Tag.new(locale)
|
83
|
-
end
|
84
|
-
|
85
|
-
def language_code
|
86
|
-
locale_tag.language.code
|
87
|
-
rescue
|
88
|
-
"en"
|
89
|
-
end
|
90
|
-
|
91
81
|
def current_user_method(&block)
|
92
82
|
@current_user = block if block.present?
|
93
83
|
end
|
@@ -123,7 +113,7 @@ module Avo
|
|
123
113
|
end
|
124
114
|
|
125
115
|
def computed_root_path
|
126
|
-
Avo
|
116
|
+
Avo.configuration.root_path
|
127
117
|
end
|
128
118
|
|
129
119
|
def feature_enabled?(feature)
|
@@ -10,21 +10,23 @@ module Avo
|
|
10
10
|
def initialize(id, **args, &block)
|
11
11
|
super(id, **args, &block)
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
add_string_prop args, :first_day_of_week, 0
|
14
|
+
add_string_prop args, :picker_format, "Y-m-d"
|
15
|
+
add_string_prop args, :format, "yyyy-LL-dd"
|
16
|
+
add_boolean_prop args, :relative
|
17
|
+
add_boolean_prop args, :disable_mobile
|
18
18
|
end
|
19
19
|
|
20
20
|
def formatted_value
|
21
21
|
return if value.blank?
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
23
|
+
value.iso8601
|
24
|
+
end
|
25
|
+
|
26
|
+
def edit_formatted_value
|
27
|
+
return nil if value.nil?
|
28
|
+
|
29
|
+
value.iso8601
|
28
30
|
end
|
29
31
|
end
|
30
32
|
end
|
@@ -2,25 +2,29 @@ module Avo
|
|
2
2
|
module Fields
|
3
3
|
class DateTimeField < DateField
|
4
4
|
attr_reader :format
|
5
|
+
attr_reader :picker_format
|
5
6
|
attr_reader :time_24hr
|
6
7
|
attr_reader :timezone
|
7
8
|
|
8
9
|
def initialize(id, **args, &block)
|
9
10
|
super(id, **args, &block)
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
12
|
+
add_boolean_prop args, :time_24hr
|
13
|
+
add_string_prop args, :picker_format, "Y-m-d H:i:S"
|
14
|
+
add_string_prop args, :format, "yyyy-LL-dd TT"
|
15
|
+
add_string_prop args, :timezone
|
14
16
|
end
|
15
17
|
|
16
18
|
def formatted_value
|
17
19
|
return nil if value.nil?
|
18
20
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
21
|
+
value.utc.to_time.iso8601
|
22
|
+
end
|
23
|
+
|
24
|
+
def edit_formatted_value
|
25
|
+
return nil if value.nil?
|
26
|
+
|
27
|
+
value.utc.iso8601
|
24
28
|
end
|
25
29
|
|
26
30
|
def fill_field(model, key, value, params)
|
@@ -32,10 +36,18 @@ module Avo
|
|
32
36
|
|
33
37
|
return model if value.blank?
|
34
38
|
|
35
|
-
model[id] = value
|
39
|
+
model[id] = utc_time(value)
|
36
40
|
|
37
41
|
model
|
38
42
|
end
|
43
|
+
|
44
|
+
def utc_time(value)
|
45
|
+
if timezone.present?
|
46
|
+
ActiveSupport::TimeZone.new(timezone).local_to_utc(Time.parse(value))
|
47
|
+
else
|
48
|
+
value
|
49
|
+
end
|
50
|
+
end
|
39
51
|
end
|
40
52
|
end
|
41
53
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Avo
|
2
|
+
module Fields
|
3
|
+
module FieldExtensions
|
4
|
+
module HasIncludeBlank
|
5
|
+
def include_blank
|
6
|
+
if @args[:include_blank] == true
|
7
|
+
placeholder || '—'
|
8
|
+
elsif @args[:include_blank] == false
|
9
|
+
false
|
10
|
+
else
|
11
|
+
@args[:include_blank]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -6,6 +6,7 @@ module Avo
|
|
6
6
|
attr_accessor :is_image
|
7
7
|
attr_accessor :is_audio
|
8
8
|
attr_accessor :direct_upload
|
9
|
+
attr_accessor :accept
|
9
10
|
|
10
11
|
def initialize(id, **args, &block)
|
11
12
|
super(id, **args, &block)
|
@@ -15,6 +16,7 @@ module Avo
|
|
15
16
|
@is_image = args[:is_image].present? ? args[:is_image] : @is_avatar
|
16
17
|
@is_audio = args[:is_audio].present? ? args[:is_audio] : false
|
17
18
|
@direct_upload = args[:direct_upload].present? ? args[:direct_upload] : false
|
19
|
+
@accept = args[:accept].present? ? args[:accept] : nil
|
18
20
|
end
|
19
21
|
|
20
22
|
def path
|
@@ -4,6 +4,7 @@ module Avo
|
|
4
4
|
attr_accessor :is_audio
|
5
5
|
attr_accessor :is_image
|
6
6
|
attr_accessor :direct_upload
|
7
|
+
attr_accessor :accept
|
7
8
|
|
8
9
|
def initialize(id, **args, &block)
|
9
10
|
super(id, **args, &block)
|
@@ -11,6 +12,7 @@ module Avo
|
|
11
12
|
@is_audio = args[:is_audio].present? ? args[:is_audio] : false
|
12
13
|
@is_image = args[:is_image].present? ? args[:is_image] : @is_avatar
|
13
14
|
@direct_upload = args[:direct_upload].present? ? args[:direct_upload] : false
|
15
|
+
@accept = args[:accept].present? ? args[:accept] : nil
|
14
16
|
end
|
15
17
|
|
16
18
|
def view_component_name
|
data/lib/avo/licensing/h_q.rb
CHANGED
@@ -121,6 +121,8 @@ module Avo
|
|
121
121
|
cache_and_return_error "HTTP connection reset error.", exception.message
|
122
122
|
rescue Errno::ECONNREFUSED => exception
|
123
123
|
cache_and_return_error "HTTP connection refused error.", exception.message
|
124
|
+
rescue OpenSSL::SSL::SSLError => exception
|
125
|
+
cache_and_return_error "OpenSSL error.", exception.message
|
124
126
|
rescue HTTParty::Error => exception
|
125
127
|
cache_and_return_error "HTTP client error.", exception.message
|
126
128
|
rescue Net::OpenTimeout => exception
|
data/lib/avo/version.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
-
|
1
|
+
require_relative "named_base_generator"
|
2
2
|
|
3
3
|
module Generators
|
4
4
|
module Avo
|
5
|
-
class ActionGenerator <
|
5
|
+
class ActionGenerator < NamedBaseGenerator
|
6
6
|
source_root File.expand_path("templates", __dir__)
|
7
|
+
|
7
8
|
class_option :standalone, type: :boolean
|
8
9
|
|
9
10
|
namespace "avo:action"
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative "../named_base_generator"
|
2
|
+
|
3
|
+
module Generators
|
4
|
+
module Avo
|
5
|
+
module Card
|
6
|
+
class ChartkickGenerator < Generators::Avo::NamedBaseGenerator
|
7
|
+
source_root File.expand_path("../templates", __dir__)
|
8
|
+
|
9
|
+
namespace "avo:card:chartkick"
|
10
|
+
desc "Add a chartkick card for your Avo dashboard."
|
11
|
+
|
12
|
+
def handle
|
13
|
+
template "cards/chartkick_card_sample.tt", "app/avo/cards/#{name.underscore}.rb"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|