motor-admin 0.2.31 → 0.2.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: