motor-admin 0.2.31 → 0.2.35

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8730558d792eeae0e0468acf367e89e7c9ff55e6fe59c64ff1b8f769fa04e554
4
- data.tar.gz: 40b909df7e968eb8c26aa2e06704371ed8b4bebed4d0cf8fce26100cf64d8ad8
3
+ metadata.gz: 1a7e4ffe16cfe1afe744f8a5c54f39858516b40d7389a0d074e7c19705181bbe
4
+ data.tar.gz: 4a7b8d35fc0e1f983d4420dd995d886204ada78404fa16874907c734a3d52976
5
5
  SHA512:
6
- metadata.gz: d1259b8f633301feaef1d0d05e54a96d5c42e841769e556e1b5382c52375633d282ce502eb87829f9dc462267c1b8e4fe31ad5f6151044b1e4d2d734c422c87d
7
- data.tar.gz: da7e9a7d859ebf45fc8ad8da2f8008cbf523ef6a3f53408d8cc31760113dfa7b459447184f14187934a627765995fc2ff83cb98571e7bec64d0a7b7d7d93f0ac
6
+ metadata.gz: 97583ffa5b4ea71e4ebc1802de3dbc2ce24ba4ad0fdfb8d746dcf70e619ecd005b1ac56472b5b86d01a5e75a34bf4aeb5d2ced7c8519f1d0f378f88602e70cd8
7
+ data.tar.gz: a4ff78ad190f975ed4635bea15dcd88f413f8e4daf8637f4fe4494818ac59a9db453c7b41443d6b81071d8573976aed90bf5037a2600385630bec569263452b1
data/README.md CHANGED
@@ -38,6 +38,7 @@ $ rails motor:install && rake db:migrate
38
38
  * [I18n](#i18n)
39
39
  * [Optimized for mobile](#optimized-for-mobile)
40
40
  * [Configurations sync between environments](#configurations-sync)
41
+ * [Authentication](#authentication)
41
42
 
42
43
  ## [Pro](https://www.getmotoradmin.com/pro)
43
44
 
@@ -284,3 +284,6 @@ en:
284
284
  hyphen: Hyphen
285
285
  comma: Comma
286
286
  slash: Slash
287
+ sql: SQL
288
+ api: API
289
+ searchable_columns: Searchable columns
@@ -284,6 +284,9 @@ es:
284
284
  hyphen: Guión
285
285
  comma: Coma
286
286
  slash: Slash
287
+ sql: SQL
288
+ api: API
289
+ searchable_columns: Columnas de búsqueda
287
290
  i:
288
291
  locale: es
289
292
  select:
@@ -280,6 +280,9 @@ pt:
280
280
  hyphen: Hífen
281
281
  comma: Vírgula
282
282
  slash: Slash
283
+ sql: SQL
284
+ api: API
285
+ searchable_columns: Colunas pesquisáveis
283
286
  i:
284
287
  locale: pt
285
288
  select:
@@ -18,5 +18,16 @@ if Rails::VERSION::MAJOR == 7
18
18
  end
19
19
  end
20
20
  end
21
+
22
+ module Contexts
23
+ class BaseContext
24
+ def preload_records(association_name, records)
25
+ TemporaryPreloadConfig.within_context do
26
+ ActiveRecord::Associations::Preloader.new(records: records,
27
+ associations: association_name).call
28
+ end
29
+ end
30
+ end
31
+ end
21
32
  end
22
33
  end
data/lib/motor/admin.rb CHANGED
@@ -39,7 +39,7 @@ module Motor
39
39
  end
40
40
 
41
41
  initializer 'motor.filter_params' do
42
- Rails.application.config.filter_parameters += %i[io]
42
+ Rails.application.config.filter_parameters += [/\Aio\z/]
43
43
  end
44
44
 
45
45
  initializer 'motor.alerts.scheduler' do
@@ -3,9 +3,8 @@
3
3
  module Motor
4
4
  module ApiQuery
5
5
  module Search
6
- SELECT_COLUMNS_AMOUNT = 2
7
- COLUMN_TYPES = BuildSchema::SEARCHABLE_COLUMN_TYPES
8
- ID_REGEXP = /\A\d+\z/.freeze
6
+ STRING_COLUMN_TYPES = %i[text string].freeze
7
+ NUMBER_COLUMN_TYPES = %i[integer float].freeze
9
8
 
10
9
  module_function
11
10
 
@@ -20,19 +19,27 @@ module Motor
20
19
  end
21
20
 
22
21
  def fetch_filters(rel, keyword)
23
- arel_filters = []
24
-
25
22
  klass = rel.klass
26
- arel_table = klass.arel_table
27
23
 
28
- arel_filters << arel_table[klass.primary_key].eq(keyword) if keyword.match?(ID_REGEXP)
24
+ selected_columns = find_searchable_columns(klass)
25
+
26
+ build_arel_filters(klass, selected_columns, keyword)
27
+ end
29
28
 
30
- string_column_names = find_searchable_columns(klass)
31
- selected_columns = select_columns(string_column_names)
29
+ def build_arel_filters(model, column_names, keyword)
30
+ arel_table = model.arel_table
32
31
 
33
- selected_columns.each { |name| arel_filters << arel_table[name].matches("%#{keyword}%") }
32
+ column_names.map do |name|
33
+ column_type = model.columns_hash[name].type
34
34
 
35
- arel_filters
35
+ if STRING_COLUMN_TYPES.include?(column_type)
36
+ arel_table[name].matches("%#{keyword}%")
37
+ elsif NUMBER_COLUMN_TYPES.include?(column_type)
38
+ arel_table[name].eq(keyword.to_f)
39
+ else
40
+ arel_table[name].eq(keyword)
41
+ end
42
+ end
36
43
  end
37
44
 
38
45
  def build_arel_or_query(filter_array)
@@ -43,23 +50,8 @@ module Motor
43
50
  end
44
51
  end
45
52
 
46
- def select_columns(columns)
47
- selected_columns =
48
- columns.grep(BuildSchema::FindDisplayColumn::DISPLAY_NAME_REGEXP).presence
49
-
50
- selected_columns ||= columns.first(SELECT_COLUMNS_AMOUNT)
51
-
52
- selected_columns
53
- end
54
-
55
53
  def find_searchable_columns(model)
56
- model.columns.map do |column|
57
- next unless column.type.in?(COLUMN_TYPES)
58
- next if column.respond_to?(:array?) && column.array?
59
- next if model.validators_on(column.name).any?(ActiveModel::Validations::InclusionValidator)
60
-
61
- column.name
62
- end.compact
54
+ model.try(:motor_searchable_columns) || Motor::BuildSchema::FindSearchableColumns.call(model)
63
55
  end
64
56
  end
65
57
  end
@@ -45,7 +45,18 @@ module Motor
45
45
 
46
46
  arel_column = reflection_model.arel_table[field]
47
47
 
48
- direction.present? ? arel_column.desc : arel_column.asc
48
+ arel_direction = direction.present? ? arel_column.desc : arel_column.asc
49
+
50
+ maybe_add_null_last(model, arel_direction)
51
+ end
52
+ end
53
+
54
+ def maybe_add_null_last(model, arel_direction)
55
+ if arel_direction.respond_to?(:nulls_last) &&
56
+ model.connection.class.name == 'ActiveRecord::ConnectionAdapters::PostgreSQLAdapter'
57
+ arel_direction.nulls_last
58
+ else
59
+ arel_direction
49
60
  end
50
61
  end
51
62
  end
@@ -87,8 +87,8 @@ module Motor
87
87
  'district' => 'building-community',
88
88
  'community' => 'building-community',
89
89
  'activity' => 'activity',
90
- 'invoice' => 'invoice',
91
- 'settlement' => 'invoice',
90
+ 'invoice' => 'file-invoice',
91
+ 'settlement' => 'file-invoice',
92
92
  'state' => 'map',
93
93
  'note' => 'note',
94
94
  'order' => 'truck-delivery',
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Motor
4
+ module BuildSchema
5
+ module FindSearchableColumns
6
+ SELECT_COLUMNS_AMOUNT = 2
7
+ COLUMN_TYPES = BuildSchema::SEARCHABLE_COLUMN_TYPES
8
+
9
+ module_function
10
+
11
+ def call(model)
12
+ columns = find_searchable_columns(model)
13
+
14
+ selected_columns =
15
+ columns.grep(BuildSchema::FindDisplayColumn::DISPLAY_NAME_REGEXP).presence
16
+
17
+ selected_columns ||= columns.first(SELECT_COLUMNS_AMOUNT)
18
+
19
+ ([model.primary_key] + selected_columns).sort
20
+ end
21
+
22
+ def find_searchable_columns(model)
23
+ model.columns.map do |column|
24
+ next unless column.type.in?(COLUMN_TYPES)
25
+ next if column.respond_to?(:array?) && column.array?
26
+ next if model.validators_on(column.name).any?(ActiveModel::Validations::InclusionValidator)
27
+
28
+ column.name
29
+ end.compact
30
+ end
31
+ end
32
+ end
33
+ end
@@ -56,6 +56,7 @@ module Motor
56
56
  models
57
57
  end
58
58
 
59
+ # rubocop:disable Metrics/MethodLength
59
60
  def build_model_schema(model)
60
61
  model_name = model.name
61
62
 
@@ -65,7 +66,7 @@ module Motor
65
66
  name: model_name.underscore,
66
67
  slug: Utils.slugify(model),
67
68
  table_name: model.table_name,
68
- class_name: model.name,
69
+ class_name: model_name,
69
70
  primary_key: model.primary_key,
70
71
  display_name: model.model_name.human(count: :many, default: model_name.titleize.pluralize),
71
72
  display_column: FindDisplayColumn.call(model),
@@ -75,11 +76,13 @@ module Motor
75
76
  scopes: fetch_scopes(model),
76
77
  actions: BuildSchema::Defaults.actions,
77
78
  tabs: BuildSchema::Defaults.tabs,
79
+ searchable_columns: FindSearchableColumns.call(model),
78
80
  custom_sql: nil,
79
81
  visible: true,
80
82
  display_primary_key: true
81
83
  }.with_indifferent_access
82
84
  end
85
+ # rubocop:enable Metrics/MethodLength
83
86
 
84
87
  def fetch_scopes(model)
85
88
  model.defined_scopes.map do |scope_name|
@@ -113,3 +113,4 @@ require_relative './build_schema/merge_schema_configs'
113
113
  require_relative './build_schema/apply_permissions'
114
114
  require_relative './build_schema/utils'
115
115
  require_relative './build_schema/defaults'
116
+ require_relative './build_schema/find_searchable_columns'
@@ -72,10 +72,14 @@ module Motor
72
72
  resources_index = Motor::Configs::LoadFromCache.load_resources.index_by(&:name)
73
73
 
74
74
  configs_hash[:resources].each do |attrs|
75
- record = resources_index[attrs[:name]] || Motor::Resource.new
75
+ record = resources_index.fetch(attrs[:name], Motor::Resource.new)
76
76
 
77
- next if record.updated_at && attrs[:updated_at] <= record.updated_at
77
+ next if record.updated_at && attrs[:updated_at] < record.updated_at
78
+ next if record.updated_at &&
79
+ attrs[:updated_at] == record.updated_at &&
80
+ attrs[:preferences] == record.preferences
78
81
 
82
+ record.updated_at_will_change!
79
83
  record.update!(attrs)
80
84
  end
81
85
  end
@@ -33,6 +33,7 @@ module Motor
33
33
  define_default_scope(klass, config)
34
34
  define_column_reflections(klass, config)
35
35
  define_associations(klass, config)
36
+ define_searchable_columns_method(klass, config)
36
37
 
37
38
  klass
38
39
  end
@@ -75,6 +76,18 @@ module Motor
75
76
  klass
76
77
  end
77
78
 
79
+ def define_searchable_columns_method(klass, config)
80
+ return if config[:searchable_columns].blank?
81
+
82
+ klass.instance_variable_set(:@__motor_searchable_columns, config[:searchable_columns])
83
+
84
+ klass.instance_eval do
85
+ def motor_searchable_columns
86
+ @__motor_searchable_columns
87
+ end
88
+ end
89
+ end
90
+
78
91
  def define_columns_hash(klass, config)
79
92
  return klass if config[:custom_sql].blank?
80
93
 
@@ -82,7 +95,13 @@ module Motor
82
95
 
83
96
  columns_hash =
84
97
  columns.each_with_object({}) do |column, acc|
85
- acc[column[:name]] = ActiveRecord::ConnectionAdapters::Column.new(column[:name], nil)
98
+ acc[column[:name]] =
99
+ ActiveRecord::ConnectionAdapters::Column.new(
100
+ column[:name],
101
+ nil,
102
+ ActiveRecord::ConnectionAdapters::SqlTypeMetadata.new(sql_type: column[:column_type],
103
+ type: column[:column_type].to_sym)
104
+ )
86
105
  end
87
106
 
88
107
  klass.instance_variable_set(:@__motor_custom_sql_columns_hash, columns_hash)
@@ -2,7 +2,8 @@
2
2
 
3
3
  module Motor
4
4
  module Resources
5
- RESOURCE_ATTRS = %w[display_name display_column icon custom_sql visible display_primary_key].freeze
5
+ RESOURCE_ATTRS = %w[display_name display_column icon custom_sql visible display_primary_key
6
+ searchable_columns].freeze
6
7
  COLUMN_ATTRS = %w[name display_name column_type access_type default_value reference virtual format].freeze
7
8
  ASSOCIATION_ATTRS = %w[name display_name model_name icon visible foreign_key primary_key options virtual
8
9
  polymorphic slug].freeze
data/lib/motor/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Motor
4
- VERSION = '0.2.31'
4
+ VERSION = '0.2.35'
5
5
  end
@@ -2601,9 +2601,9 @@
2601
2601
  "icons/zoom-out.svg.gz": "icons/zoom-out.svg.gz",
2602
2602
  "icons/zoom-question.svg": "icons/zoom-question.svg",
2603
2603
  "icons/zoom-question.svg.gz": "icons/zoom-question.svg.gz",
2604
- "main-bbd8f938004172b512b9.css.gz": "main-bbd8f938004172b512b9.css.gz",
2605
- "main-bbd8f938004172b512b9.js.LICENSE.txt": "main-bbd8f938004172b512b9.js.LICENSE.txt",
2606
- "main-bbd8f938004172b512b9.js.gz": "main-bbd8f938004172b512b9.js.gz",
2607
- "main.css": "main-bbd8f938004172b512b9.css",
2608
- "main.js": "main-bbd8f938004172b512b9.js"
2604
+ "main-20a597f4a4ce450fb62c.css.gz": "main-20a597f4a4ce450fb62c.css.gz",
2605
+ "main-20a597f4a4ce450fb62c.js.LICENSE.txt": "main-20a597f4a4ce450fb62c.js.LICENSE.txt",
2606
+ "main-20a597f4a4ce450fb62c.js.gz": "main-20a597f4a4ce450fb62c.js.gz",
2607
+ "main.css": "main-20a597f4a4ce450fb62c.css",
2608
+ "main.js": "main-20a597f4a4ce450fb62c.js"
2609
2609
  }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: motor-admin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.31
4
+ version: 0.2.35
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pete Matsyburka
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-25 00:00:00.000000000 Z
11
+ date: 2021-12-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord-filter
@@ -191,6 +191,7 @@ files:
191
191
  - lib/motor/build_schema/defaults.rb
192
192
  - lib/motor/build_schema/find_display_column.rb
193
193
  - lib/motor/build_schema/find_icon.rb
194
+ - lib/motor/build_schema/find_searchable_columns.rb
194
195
  - lib/motor/build_schema/load_from_rails.rb
195
196
  - lib/motor/build_schema/merge_schema_configs.rb
196
197
  - lib/motor/build_schema/reorder_schema.rb
@@ -1525,8 +1526,8 @@ files:
1525
1526
  - ui/dist/icons/zoom-money.svg.gz
1526
1527
  - ui/dist/icons/zoom-out.svg.gz
1527
1528
  - ui/dist/icons/zoom-question.svg.gz
1528
- - ui/dist/main-bbd8f938004172b512b9.css.gz
1529
- - ui/dist/main-bbd8f938004172b512b9.js.gz
1529
+ - ui/dist/main-20a597f4a4ce450fb62c.css.gz
1530
+ - ui/dist/main-20a597f4a4ce450fb62c.js.gz
1530
1531
  - ui/dist/manifest.json
1531
1532
  homepage:
1532
1533
  licenses: