marty 1.0.8 → 1.0.9

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
  SHA1:
3
- metadata.gz: b1ea4f6bcc7d2dc454f65ba38f7cc922e7778354
4
- data.tar.gz: efa8f6b874e09398b171995daeb4cc898833bed5
3
+ metadata.gz: 9f7ab7a282240ba4ee18dc965f93bdb5dc90dda4
4
+ data.tar.gz: 59917c67864d40e9d849695798b11fc650c2b060
5
5
  SHA512:
6
- metadata.gz: 2df7d3c0f2dd6f1146d65320ba6e6386895d52e7542144e489896193f86f545777d2eecb7ae951f4b70cef9f62ae2f791a8f2ff489f2159f48f97c7646d449b3
7
- data.tar.gz: cbf82d6f70c0e1546a17b4c3d8be986c7f95a81f52bbe7c09ffde36aa71b7a1c5a1264525c5864520233925502a058756888d6440ed380a1152a04f653f1adae
6
+ metadata.gz: 56e52e10fad378a499de7debcc9528dcc1127f16a8802e907333d9d65ea7aab3320a8b53042e99ac16f1a354cc9359d8d14c99d690693fa5d4d67a2ef8609ef1
7
+ data.tar.gz: 5e38cb0f66dcdec946da7ca79ff44de3f0c60bc68a6982a81e1e8961b0c396a3d92a480fac9e96f51df10c24e0ab01e842c52390b7341859db921e455caff06a
@@ -63,14 +63,22 @@ module Marty
63
63
  editor_config = {
64
64
  trigger_action: :all,
65
65
  xtype: :combo,
66
- store: klass::VALUES,
66
+
67
+ # hacky: extjs has issues with forceSelection true and clearing combos
68
+ store: klass::VALUES + ['---'],
69
+ forceSelection: true,
67
70
  }
68
71
  c.merge!(
69
72
  column_config: { editor: editor_config },
70
73
  field_config: editor_config,
71
74
  type: :string,
75
+ setter: enum_setter(c.name),
72
76
  )
73
77
  end
78
+
79
+ def enum_setter(name)
80
+ lambda {|r, v| r.send("#{name}=", v == '---' || v.empty? ? nil : v)}
81
+ end
74
82
  end
75
83
  end
76
84
  end
@@ -56,6 +56,7 @@ class Marty::MainAuthApp < Marty::AuthApp
56
56
  :config_view,
57
57
  :api_auth_view,
58
58
  :reload_scripts,
59
+ :load_seed,
59
60
  ],
60
61
  }
61
62
  end
@@ -173,6 +174,13 @@ class Marty::MainAuthApp < Marty::AuthApp
173
174
  a.disabled = !self.class.has_admin_perm?
174
175
  end
175
176
 
177
+ action :load_seed do |a|
178
+ a.text = 'Load Seeds'
179
+ a.tooltip = 'Load Seeds'
180
+ a.icon = :arrow_rotate_clockwise
181
+ a.disabled = !self.class.has_admin_perm?
182
+ end
183
+
176
184
  ######################################################################
177
185
  # Postings
178
186
 
@@ -206,6 +214,12 @@ class Marty::MainAuthApp < Marty::AuthApp
206
214
  }
207
215
  JS
208
216
 
217
+ c.netzke_on_load_seed = l(<<-JS)
218
+ function(params) {
219
+ this.server.loadSeed({});
220
+ }
221
+ JS
222
+
209
223
  c.netzke_on_select_now = l(<<-JS)
210
224
  function(params) {
211
225
  this.server.selectPosting({});
@@ -272,6 +286,11 @@ class Marty::MainAuthApp < Marty::AuthApp
272
286
  Marty::Script.load_scripts
273
287
  client.netzke_notify 'Scripts have been reloaded'
274
288
  end
289
+
290
+ endpoint :load_seed do |params|
291
+ Rails.application.load_seed
292
+ client.netzke_notify 'Seeds have been loaded'
293
+ end
275
294
  end
276
295
 
277
296
  MainAuthApp = Marty::MainAuthApp
@@ -7,4 +7,6 @@ module Marty::PgEnum
7
7
 
8
8
  index
9
9
  end
10
+
11
+ alias_method :find_by_name, :[]
10
12
  end
@@ -149,6 +149,51 @@ module Netzke::Basepack::DataAdapters
149
149
  relation.count
150
150
  end
151
151
 
152
+ ######################################################################
153
+ # The following is a hack to get around Netzke's broken handling
154
+ # of filtering on PostgreSQL enums columns.
155
+ def predicates_for_and_conditions(conditions)
156
+ return nil if conditions.empty?
157
+
158
+ predicates = conditions.map do |q|
159
+ q = HashWithIndifferentAccess.new(q)
160
+
161
+ attr = q[:attr]
162
+ method, assoc = method_and_assoc(attr)
163
+
164
+ arel_table = assoc ? Arel::Table.new(assoc.klass.table_name.to_sym) :
165
+ @model.arel_table
166
+
167
+ value = q["value"]
168
+ op = q["operator"]
169
+
170
+ attr_type = attr_type(attr)
171
+
172
+ case attr_type
173
+ when :datetime
174
+ update_predecate_for_datetime(arel_table[method], op, value.to_date)
175
+ when :string, :text
176
+ update_predecate_for_string(arel_table[method], op, value)
177
+ when :boolean
178
+ update_predecate_for_boolean(arel_table[method], op, value)
179
+ when :date
180
+ update_predecate_for_rest(arel_table[method], op, value.to_date)
181
+ when :enum
182
+ # HACKY! monkey patching happens here...
183
+ update_predecate_for_enum(arel_table[method], op, value)
184
+ else
185
+ update_predecate_for_rest(arel_table[method], op, value)
186
+ end
187
+ end
188
+
189
+ # join them by AND
190
+ predicates[1..-1].inject(predicates.first){ |r,p| r.and(p) }
191
+ end
192
+
193
+ def update_predecate_for_enum(table, op, value)
194
+ col = Arel::Nodes::NamedFunction.new("CAST", [table.as("TEXT")])
195
+ col.matches "%#{value}%"
196
+ end
152
197
  end
153
198
  end
154
199
 
@@ -1,3 +1,3 @@
1
1
  module Marty
2
- VERSION = "1.0.8"
2
+ VERSION = "1.0.9"
3
3
  end
@@ -0,0 +1,27 @@
1
+ class Gemini::CmAuthApp < Marty::MainAuthApp
2
+
3
+ CATEGORY_COMPONENTS = [
4
+ :loan_program_view,
5
+ ]
6
+
7
+ def data_menus
8
+ basic = [
9
+ {
10
+ text: 'Pricing Config.',
11
+ icon: icon_hack(:database_key),
12
+ menu: [
13
+ :loan_program_view,
14
+ ],
15
+ }
16
+ ]
17
+ end
18
+
19
+ action :loan_program_view do |a|
20
+ a.text = a.tooltip = 'Loan Programs'
21
+ a.handler = :netzke_load_component_by_action
22
+ end
23
+
24
+ component :loan_program_view do |c|
25
+ c.klass = Gemini::LoanProgramView
26
+ end
27
+ end
@@ -0,0 +1,28 @@
1
+ class Gemini::LoanProgramView < Marty::GridAppendOnly
2
+ include Marty::Extras::Layout
3
+
4
+ has_marty_permissions create: :dev,
5
+ read: :any,
6
+ update: :dev,
7
+ delete: :dev
8
+
9
+ def configure(c)
10
+ super
11
+
12
+ c.title = "Loan Programs"
13
+ c.model = "Gemini::LoanProgram"
14
+ c.attributes = [
15
+ :name,
16
+ :amortization_type__name,
17
+ :mortgage_type__name,
18
+ :streamline_type__name,
19
+ :enum_state,
20
+ ]
21
+
22
+ c.store_config.merge!({sorters: [{property: :name, direction: 'ASC'}]})
23
+ end
24
+
25
+ attribute :enum_state do |c|
26
+ enum_column(c, Gemini::EnumState)
27
+ end
28
+ end
@@ -1,7 +1,5 @@
1
- require 'marty/main_auth_app'
2
-
3
1
  class ComponentsController < Marty::ApplicationController
4
2
  def home
5
- render inline: "<%= netzke :'main_auth_app' %>", layout: true
3
+ render inline: "<%= netzke :'cm_auth_app', klass: Gemini::CmAuthApp %>", layout: true
6
4
  end
7
- end
5
+ end
@@ -0,0 +1,63 @@
1
+ class Gemini::EnumState < ActiveRecord::Base
2
+ extend Marty::PgEnum
3
+
4
+ VALUES = Set[
5
+ "AL",
6
+ "AK",
7
+ "AZ",
8
+ "AR",
9
+ "CA",
10
+ "CO",
11
+ "CT",
12
+ "DE",
13
+ "DC",
14
+ "FL",
15
+ "GA",
16
+ "HI",
17
+ "ID",
18
+ "IL",
19
+ "IN",
20
+ "IA",
21
+ "KS",
22
+ "KY",
23
+ "LA",
24
+ "ME",
25
+ "MD",
26
+ "MA",
27
+ "MI",
28
+ "MN",
29
+ "MS",
30
+ "MO",
31
+ "MT",
32
+ "NE",
33
+ "NV",
34
+ "NH",
35
+ "NJ",
36
+ "NM",
37
+ "NY",
38
+ "NC",
39
+ "ND",
40
+ "OH",
41
+ "OK",
42
+ "OR",
43
+ "PA",
44
+ "RI",
45
+ "SC",
46
+ "SD",
47
+ "TN",
48
+ "TX",
49
+ "UT",
50
+ "VT",
51
+ "VA",
52
+ "WA",
53
+ "WV",
54
+ "WI",
55
+ "WY",
56
+
57
+ # US Territories (FIXME: incomplete)
58
+ "AS",
59
+ "GU",
60
+ "PR",
61
+ "VI",
62
+ ]
63
+ end
@@ -5,6 +5,8 @@ class Gemini::LoanProgram < ActiveRecord::Base
5
5
  has_mcfly
6
6
  mcfly_validates_uniqueness_of :name
7
7
 
8
+ validates_presence_of :name, :amortization_type, :mortgage_type, :streamline_type
9
+
8
10
  belongs_to :amortization_type
9
11
  belongs_to :mortgage_type
10
12
  belongs_to :streamline_type
@@ -0,0 +1,16 @@
1
+ class CreateEnums < ActiveRecord::Migration
2
+ def change
3
+ values = Gemini::EnumState::VALUES
4
+ str_values =
5
+ values.map {|v| ActiveRecord::Base.connection.quote v}.join ','
6
+
7
+ ActiveRecord::Base.schema_migrations_table_name
8
+
9
+ # FIXME: very crude
10
+ name = 'enum_states'
11
+
12
+ execute <<-SQL
13
+ CREATE TYPE #{name} AS ENUM (#{str_values});
14
+ SQL
15
+ end
16
+ end
@@ -16,6 +16,7 @@ class CreateLoanPrograms < ActiveRecord::Migration
16
16
  t.decimal "arm_lifetime_cap_percent", precision: 7, scale: 4
17
17
  t.integer "arm_index_type_id"
18
18
  t.decimal "arm_margin_rate_percent", precision: 7, scale: 4
19
+ t.pg_enum :enum_state, null: true
19
20
  end
20
21
  McflyMigration.new.add_sql 'gemini_loan_programs', false
21
22
  end
@@ -0,0 +1,125 @@
1
+ require 'spec_helper'
2
+
3
+ feature 'test netzke + pg_enum compatibility', js: true do
4
+
5
+ before(:all) do
6
+ @clean_file = "/tmp/clean_#{Process.pid}.psql"
7
+ save_clean_db(@clean_file)
8
+
9
+ populate_test_users
10
+ end
11
+
12
+ after(:all) do
13
+ restore_clean_db(@clean_file)
14
+ end
15
+
16
+ it 'shows netzke grid combobox works w pg_enums' do
17
+ log_in_as('dev1')
18
+
19
+ by 'navigating to loan program screen' do
20
+ press('Pricing Config.')
21
+ press('Loan Programs')
22
+ end
23
+
24
+ lp_grid = netzke_find('loan_program_view')
25
+ amort_combo = netzke_find('amortization_type__name', 'combobox')
26
+ mortgage_combo = netzke_find('mortgage_type__name', 'combobox')
27
+ streamline_combo = netzke_find('streamline_type__name', 'combobox')
28
+ state_combo = netzke_find('enum_state', 'combobox')
29
+
30
+ and_by 'bring up new window' do
31
+ press('Add')
32
+ end
33
+
34
+ and_by 'fill form minus enum value' do
35
+ within(:gridpanel, 'add_window', match: :first) do
36
+ fill_in("Name", with: 'a_l_p')
37
+
38
+ amort_combo.click
39
+ amort_combo.select_values('Fixed')
40
+
41
+ mortgage_combo.click
42
+ mortgage_combo.select_values('FHA')
43
+
44
+ streamline_combo.click
45
+ streamline_combo.select_values('DURP')
46
+
47
+ press('OK')
48
+ end
49
+
50
+ wait_for_ajax
51
+ expect(lp_grid.row_count).to eq(1)
52
+ end
53
+
54
+ and_by 'bring up new window' do
55
+ press('Add')
56
+ end
57
+
58
+ and_by 'fill form w enum value & duplicated name (error), then fix' do
59
+ within(:gridpanel, 'add_window', match: :first) do
60
+ fill_in("Name", with: 'a_l_p')
61
+ amort_combo.click
62
+ amort_combo.select_values('Fixed')
63
+
64
+ mortgage_combo.click
65
+ mortgage_combo.select_values('FHA')
66
+
67
+ streamline_combo.click
68
+ streamline_combo.select_values('DURP')
69
+
70
+ state_combo.click
71
+ state_combo.select_values('CA')
72
+
73
+ press('OK')
74
+
75
+ expect(find(:msg)).to have_content 'Name - record must be unique'
76
+
77
+ fill_in("Name", with: 'a_l_p_2')
78
+ press('OK')
79
+ end
80
+
81
+ wait_for_ajax
82
+ aggregate_failures do
83
+ expect(lp_grid.row_count).to eq(2)
84
+ expect(lp_grid.get_row_vals(2)).to netzke_include({enum_state: 'CA'})
85
+ end
86
+ end
87
+
88
+ and_by 'delete a row' do
89
+ lp_grid.select_row(1)
90
+ press('Delete')
91
+ press('Yes')
92
+ wait_for_ajax
93
+ expect(lp_grid.row_count).to eq(1)
94
+ end
95
+
96
+ and_by 'bring up new window' do
97
+ press('Add')
98
+ end
99
+
100
+ and_by 'fill form w --- for enum value' do
101
+ within(:gridpanel, 'add_window', match: :first) do
102
+ fill_in("Name", with: 'a_l_p')
103
+ amort_combo.click
104
+ amort_combo.select_values('Fixed')
105
+
106
+ mortgage_combo.click
107
+ mortgage_combo.select_values('FHA')
108
+
109
+ streamline_combo.click
110
+ streamline_combo.select_values('DURP')
111
+
112
+ state_combo.click
113
+ state_combo.select_values('---')
114
+
115
+ press('OK')
116
+ end
117
+
118
+ wait_for_ajax
119
+ aggregate_failures do
120
+ expect(lp_grid.row_count).to eq(2)
121
+ expect(lp_grid.get_row_vals(1)).to netzke_include({enum_state: nil})
122
+ end
123
+ end
124
+ end
125
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: marty
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.8
4
+ version: 1.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arman Bostani
@@ -14,7 +14,7 @@ authors:
14
14
  autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
- date: 2016-09-01 00:00:00.000000000 Z
17
+ date: 2016-09-19 00:00:00.000000000 Z
18
18
  dependencies:
19
19
  - !ruby/object:Gem::Dependency
20
20
  name: pg
@@ -469,6 +469,8 @@ files:
469
469
  - spec/dummy/Rakefile
470
470
  - spec/dummy/app/assets/client/application.css
471
471
  - spec/dummy/app/assets/client/application.js
472
+ - spec/dummy/app/components/gemini/cm_auth_app.rb
473
+ - spec/dummy/app/components/gemini/loan_program_view.rb
472
474
  - spec/dummy/app/controllers/application_controller.rb
473
475
  - spec/dummy/app/controllers/components_controller.rb
474
476
  - spec/dummy/app/helpers/application_helper.rb
@@ -477,6 +479,7 @@ files:
477
479
  - spec/dummy/app/models/gemini/amortization_type.rb
478
480
  - spec/dummy/app/models/gemini/bud_category.rb
479
481
  - spec/dummy/app/models/gemini/entity.rb
482
+ - spec/dummy/app/models/gemini/enum_state.rb
480
483
  - spec/dummy/app/models/gemini/extras/data_import.rb
481
484
  - spec/dummy/app/models/gemini/extras/settlement_import.rb
482
485
  - spec/dummy/app/models/gemini/fannie_bup.rb
@@ -508,6 +511,7 @@ files:
508
511
  - spec/dummy/config/initializers/wrap_parameters.rb
509
512
  - spec/dummy/config/locales/en.yml
510
513
  - spec/dummy/config/routes.rb
514
+ - spec/dummy/db/migrate/20140000000000_create_enums.rb
511
515
  - spec/dummy/db/migrate/20140801000000_create_groupings.rb
512
516
  - spec/dummy/db/migrate/20150406171536_create_categories.rb
513
517
  - spec/dummy/db/migrate/20150408200916_create_loan_programs.rb
@@ -1537,6 +1541,7 @@ files:
1537
1541
  - spec/dummy/tmp/.gitkeep
1538
1542
  - spec/features/auth_app_spec.rb
1539
1543
  - spec/features/data_import_spec.rb
1544
+ - spec/features/enum_spec.rb
1540
1545
  - spec/features/javascripts/job_dashboard_live_search.js.coffee
1541
1546
  - spec/features/javascripts/login.js.coffee
1542
1547
  - spec/features/jobs_dashboard_spec.rb