wco_models 3.1.0.154 → 3.1.0.157

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/wco/utils.scss +11 -1
  3. data/app/controllers/wco/invoices_controller.rb +5 -24
  4. data/app/controllers/wco/leads_controller.rb +24 -20
  5. data/app/controllers/wco/sites_controller.rb +9 -0
  6. data/app/models/wco/invoice.rb +25 -1
  7. data/app/models/wco/office_action_template.rb +3 -3
  8. data/app/models/wco/site.rb +112 -1
  9. data/app/models/wco/sitemap_path.rb +20 -0
  10. data/app/models/wco_email/email_filter.rb +8 -0
  11. data/app/models/wco_email/email_filter_condition.rb +17 -0
  12. data/app/models/wco_email/message.rb +4 -1
  13. data/app/models/wco_game/location.rb +257 -0
  14. data/app/models/wco_game/marker.rb +9 -0
  15. data/app/views/layouts/wco/application.haml +3 -0
  16. data/app/views/wco/_main_header.haml +33 -30
  17. data/app/views/wco/leads/_form.haml +6 -5
  18. data/app/views/wco/leads/_list.haml +16 -0
  19. data/app/views/wco/leads/{_index.haml → _table.haml} +1 -1
  20. data/app/views/wco/leads/index.haml +1 -1
  21. data/app/views/wco/leads/show.haml +4 -4
  22. data/app/views/wco/sitemap_paths/_form.haml +18 -0
  23. data/app/views/wco/sitemap_paths/_index.haml +15 -0
  24. data/app/views/wco/sites/show.haml +16 -6
  25. data/app/views/wco/tags/_header.haml +4 -6
  26. data/app/views/wco/tags/_index.haml +1 -0
  27. data/app/views/wco/tags/_menuitem.haml +9 -0
  28. data/app/views/wco/tags/index.haml +1 -1
  29. data/app/views/wco/tags/show.haml +7 -2
  30. data/config/routes.rb +2 -0
  31. metadata +12 -5
  32. data/app/views/wco/leads/_index_rows.haml +0 -11
  33. /data/app/views/wco/photos/{_form.haml → _form.haml-trash} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8214f97a78a923e7696ac257e51c35e82735e5f49ee72fb5323897c263494eed
4
- data.tar.gz: 50a95c9ae5bc39baf0f5ed8c959b537219e6646accffd52f46577941c393835e
3
+ metadata.gz: f1d7c8e819f70c838d7784f3c628844e554e86f33b473c78db9552d7a1fbd7b0
4
+ data.tar.gz: 513a0bcd49ce21e5bdf59c776d97656969b39783d2cb54e946642ca7f0ef6aba
5
5
  SHA512:
6
- metadata.gz: 2ee8c67d727e601dbf625f4309651d56611f147852e50091bb0f8144b4b25aa382a88268fce8475a975157a9fd01e97d8bc7bdc06c980dd02084fe47eb6683c9
7
- data.tar.gz: 7356863e168fc520d0dd7ba14a9a4e02bd4b77b97b92a00df164569f0136162446a843189495fde59eac51d804cae0a93adccfc99b2a292aca8c6af579cb3bc1
6
+ metadata.gz: a03e9edbd32ffc5a3844fab246ea8aca3c3b88a206b2aebb65d9b92ab6162cee11bd66d94e54e35503701e0b705578079fb0886e45ab1cc1140826de6725f6c9
7
+ data.tar.gz: 0ebd890f1f25d37bf40395098185f532d50e0e566e65fffadc9f6e41861ada1e33e388c53b08eebb6f2334ac75209063c881d2de1ac1b0d71a22a79d55dad17f
@@ -167,7 +167,7 @@ textarea.monospace {
167
167
  /* M */
168
168
 
169
169
  .maxwidth {
170
- width: 1000px;
170
+ max-width: 1000px; /* @TODO: this would be responsive by-breakpoint _vp_ 2024-04-23 */
171
171
  margin: auto;
172
172
  }
173
173
 
@@ -188,6 +188,16 @@ textarea.monospace {
188
188
  width: calc( 100% - 1em );
189
189
  }
190
190
 
191
+ /* R */
192
+
193
+ label.required {
194
+ &:after {
195
+ content: ' *';
196
+ color: red;
197
+ }
198
+ }
199
+
200
+
191
201
  /* S */
192
202
  .spacer-small {
193
203
  height: 20px;
@@ -56,32 +56,13 @@ class Wco::InvoicesController < Wco::ApplicationController
56
56
  @invoice = Wco::Invoice.new params[:invoice].permit!
57
57
  authorize! :create, @invoice
58
58
 
59
- stripe_invoice = Stripe::Invoice.create({
60
- customer: @invoice.leadset.customer_id,
61
- collection_method: 'send_invoice',
62
- days_until_due: 0,
63
- # collection_method: 'charge_automatically',
64
- pending_invoice_items_behavior: 'exclude',
65
- })
66
- params[:invoice][:items].each do |item|
67
- stripe_price = Wco::Price.find( item[:price_id] ).price_id
68
- puts! stripe_price, 'stripe_price'
69
- invoice_item = Stripe::InvoiceItem.create({
70
- customer: @invoice.leadset.customer_id,
71
- price: stripe_price,
72
- invoice: stripe_invoice.id,
73
- quantity: item[:quantity],
74
- })
75
- end
76
- Stripe::Invoice.finalize_invoice( stripe_invoice[:id] )
77
- if params[:do_send]
78
- Stripe::Invoice.send_invoice(stripe_invoice[:id])
79
- flash_notice "Scheduled to send the invoice via stripe."
80
- end
81
- @invoice.update_attributes({ invoice_id: stripe_invoice[:id] })
82
-
83
59
  if @invoice.save
84
60
  flash_notice "Created the invoice."
61
+
62
+ if params[:do_send]
63
+ Stripe::Invoice.send_invoice(@invoice[:invoice_id])
64
+ end
65
+
85
66
  redirect_to action: :show, id: @invoice.id
86
67
  else
87
68
  flash_alert "Cannot create invoice: #{@invoice.errors.messages}"
@@ -1,14 +1,23 @@
1
1
 
2
2
  class Wco::LeadsController < Wco::ApplicationController
3
-
4
3
  before_action :set_lists
5
4
 
6
5
  def create
7
- params[:lead][:tags].delete ''
8
- params[:lead][:leadset] = nil if params[:lead][:leadset].blank?
6
+ params[:lead][:tag_ids]&.delete ''
7
+ params[:lead].delete :leadset_id if params[:lead][:leadset_id].blank?
9
8
 
10
9
  @lead = Wco::Lead.new params[:lead].permit!
11
10
  authorize! :create, @lead
11
+
12
+ if params[:lead][:photo]
13
+ photo = Wco::Photo.new photo: params[:lead][:photo]
14
+ photo.is_public = true
15
+ if photo.save
16
+ @lead.photo = photo
17
+ end
18
+ params[:lead].delete :photo
19
+ end
20
+
12
21
  if @lead.save
13
22
  flash_notice 'ok'
14
23
  else
@@ -26,8 +35,6 @@ class Wco::LeadsController < Wco::ApplicationController
26
35
  authorize! :index, Wco::Lead
27
36
  @leads = Wco::Lead.all
28
37
 
29
-
30
-
31
38
  if params[:q].present?
32
39
  q = params[:q].downcase
33
40
  @leads = @leads.any_of(
@@ -41,19 +48,6 @@ class Wco::LeadsController < Wco::ApplicationController
41
48
  end
42
49
  end
43
50
 
44
- # if params[:q_tag_ids].present?
45
- # carry = nil
46
- # params[:q_tag_ids].each do |term_id|
47
- # lts = LeadTag.where({ term_id: term_id }).map(&:lead_id)
48
- # if carry
49
- # carry = carry & lts
50
- # else
51
- # carry = lts
52
- # end
53
- # end
54
- # @leads = Lead.where({ :id.in => carry })
55
- # end
56
-
57
51
  @leads = @leads.page( params[:leads_page ] ).per( current_profile.per_page )
58
52
  end
59
53
 
@@ -77,11 +71,21 @@ class Wco::LeadsController < Wco::ApplicationController
77
71
  end
78
72
 
79
73
  def update
80
- params[:lead][:tags].delete ''
81
- params[:lead].delete :leadset if params[:lead][:leadset].blank?
74
+ params[:lead][:tag_ids]&.delete ''
75
+ params[:lead].delete :leadset_id if params[:lead][:leadset_id].blank?
82
76
 
83
77
  @lead = Wco::Lead.find params[:id]
84
78
  authorize! :update, @lead
79
+
80
+ if params[:lead][:photo]
81
+ photo = Wco::Photo.new photo: params[:lead][:photo]
82
+ photo.is_public = true
83
+ if photo.save
84
+ @lead.photo = photo
85
+ end
86
+ params[:lead].delete :photo
87
+ end
88
+
85
89
  if @lead.update params[:lead].permit!
86
90
  flash_notice 'ok'
87
91
  else
@@ -1,6 +1,13 @@
1
1
 
2
2
  class Wco::SitesController < Wco::ApplicationController
3
3
 
4
+ def check_sitemap
5
+ @site = Wco::Site.find params[:id]
6
+ authorize! :check_sitemap, @site
7
+ @site.check_sitemap
8
+ redirect_to request.referrer
9
+ end
10
+
4
11
  def create
5
12
  @site = Wco::Site.new params[:site].permit!
6
13
  authorize! :create, @site
@@ -41,6 +48,8 @@ class Wco::SitesController < Wco::ApplicationController
41
48
  def show
42
49
  @site = Wco::Site.find params[:id]
43
50
  authorize! :show, @site
51
+
52
+ @new_sitemap_path = Wco::SitemapPath.new( site_id: @site.id )
44
53
  end
45
54
 
46
55
  def update
@@ -14,6 +14,8 @@ class Wco::Invoice
14
14
  include Mongoid::Paranoia
15
15
  store_in collection: 'ish_invoice'
16
16
 
17
+ attr_accessor :is_stripe
18
+
17
19
  field :email, type: String
18
20
 
19
21
  field :invoice_id, type: String # stripe
@@ -35,7 +37,29 @@ class Wco::Invoice
35
37
  field :description, type: String
36
38
  field :items, type: Array # used by stripe
37
39
 
38
-
40
+ before_validation :create_stripe, on: :create
41
+ def create_stripe
42
+ if is_stripe
43
+ stripe_invoice = Stripe::Invoice.create({
44
+ customer: leadset.customer_id,
45
+ collection_method: 'send_invoice',
46
+ days_until_due: 0,
47
+ # collection_method: 'charge_automatically',
48
+ pending_invoice_items_behavior: 'exclude',
49
+ })
50
+ items.each do |item|
51
+ stripe_price = Wco::Price.find( item[:price_id] ).price_id
52
+ invoice_item = Stripe::InvoiceItem.create({
53
+ customer: leadset.customer_id,
54
+ price: stripe_price,
55
+ invoice: stripe_invoice.id,
56
+ quantity: item[:quantity],
57
+ })
58
+ end
59
+ Stripe::Invoice.finalize_invoice( stripe_invoice[:id] )
60
+ self.invoice_id = stripe_invoice[:id]
61
+ end
62
+ end
39
63
 
40
64
  ## Prawn/pdf unit of measure is 1/72"
41
65
  ## Canvas width: 612, height: 792
@@ -29,13 +29,13 @@ class Wco::OfficeActionTemplate
29
29
  has_many :prev_ties, class_name: 'OfficeActionTemplateTie', inverse_of: :next_office_action_template
30
30
  accepts_nested_attributes_for :ties
31
31
 
32
+ has_and_belongs_to_many :email_filters, class_name: WcoEmail::EmailFilter
33
+
32
34
  def to_s
33
35
  "#{slug}"
34
36
  end
35
-
36
37
  def self.list
37
38
  [[nil,nil]] + all.map { |ttt| [ ttt.slug, ttt.id ] }
38
39
  end
39
-
40
40
  end
41
- OAT ||= Wco::OfficeActionTemplate
41
+ # OAT ||= Wco::OfficeActionTemplate
@@ -14,8 +14,11 @@ class Wco::Site
14
14
  [nil] + KINDS
15
15
  end
16
16
 
17
- has_many :publishers # , class_name: 'Wco::Publisher'
17
+
18
18
  has_many :headlines # , class_name: 'Wco::Newstitle'
19
+ has_many :logs, inverse_of: :obj
20
+ has_many :publishers # , class_name: 'Wco::Publisher'
21
+ has_many :sitemap_paths, class_name: 'Wco::SitemapPath'
19
22
  has_many :tags, class_name: 'Wco::Tag'
20
23
 
21
24
  field :slug
@@ -101,4 +104,112 @@ class Wco::Site
101
104
  puts "ok"
102
105
  end
103
106
 
107
+ def check_sitemap
108
+ results = []
109
+ total_count = 0
110
+ error_count = 0
111
+
112
+ sitemap_paths.each do |check|
113
+ total_count += 1
114
+
115
+ # puts "Checking #{check[:path]}:"
116
+ if check[:selector]
117
+ begin
118
+ body = HTTParty.get( "#{origin}#{check[:path]}" ).body
119
+ rescue OpenSSL::SSL::SSLError => err
120
+ results.push "NOT OK [ssl-exception] #{check[:path]}".red
121
+ logg "NOT OK [ssl-exception] #{check[:path]}"
122
+ check.update status: 'NOT OK'
123
+
124
+ next
125
+ end
126
+ doc = Nokogiri::HTML( body )
127
+ out = doc.search check[:selector]
128
+ if out.present?
129
+ results.push "OK #{check[:path]}"
130
+ logg "OK #{check[:path]}"
131
+ check.update status: 'OK'
132
+ else
133
+ results.push "NOT OK [selector-missing] #{check[:path]}".red
134
+ logg "NOT OK [selector-missing] #{check[:path]}"
135
+ check.update status: 'NOT OK'
136
+ error_count += 1
137
+ end
138
+
139
+ if check[:meta_description]
140
+ out = doc.search( 'head meta[name="description"]' )[0]['content']
141
+ if check[:meta_description] == out
142
+ results.push "OK #{check[:path]} meta_description"
143
+ logg "OK #{check[:path]} meta_description"
144
+ check.update status: 'OK'
145
+ else
146
+ results.push "NOT OK [meta-description-missing] #{check[:path]}".red
147
+ logg "NOT OK [meta-description-missing] #{check[:path]}"
148
+ check.update status: 'NOT OK'
149
+ error_count += 1
150
+ end
151
+ end
152
+
153
+ elsif check[:redirect_to]
154
+ out = HTTParty.get( "#{origin}#{check[:path]}", follow_redirects: false )
155
+ if( out.headers[:location] == check[:redirect_to] ||
156
+ out.headers[:location] == "#{origin}#{check[:redirect_to]}" )
157
+ results.push "OK #{check[:path]}"
158
+ logg "OK #{check[:path]}"
159
+ check.update status: 'OK'
160
+ else
161
+ results.push "NOT OK [redirect-missing] #{check[:path]}".red
162
+ logg "NOT OK [redirect-missing] #{check[:path]}"
163
+ check.update status: 'NOT OK'
164
+
165
+ puts!( out.response, 'response' ) if DEBUG
166
+ # puts!( out.body, 'body' ) if DEBUG
167
+
168
+ error_count += 1
169
+
170
+ puts "NOT OK #{check[:path]}".red
171
+ puts out.headers[:location]
172
+ puts check[:redirect_to]
173
+ end
174
+ else
175
+ results.push "SKIP #{check[:path]}"
176
+ logg "SKIP #{check[:path]}"
177
+ check.update status: 'SKIP'
178
+ end
179
+
180
+ if check[:selectors]
181
+ check[:selectors].each do |selector|
182
+ body = HTTParty.get( "#{origin}#{check[:path]}" ).body
183
+ doc = Nokogiri::HTML( body )
184
+ out = doc.search selector
185
+ if out.present?
186
+ results.push "OK #{check[:path]} selectors:#{selector}"
187
+ logg "OK #{check[:path]} selectors:#{selector}"
188
+ check.update status: 'OK'
189
+ else
190
+ results.push "NOT OK [selectors-missing:#{selector}] #{check[:path]}".red
191
+ logg "NOT OK [selectors-missing:#{selector}] #{check[:path]}"
192
+ check.update status: 'NOT OK'
193
+ error_count += 1
194
+ end
195
+ end
196
+ end
197
+
198
+ end
199
+
200
+ puts "Results:".green
201
+ results.each do |r|
202
+ puts r
203
+ end
204
+ puts "Total count: #{total_count}"
205
+ puts "Error count: #{error_count}"
206
+ end
207
+
208
+ def logg msg
209
+ Wco::Log.create!({
210
+ message: msg,
211
+ obj: self,
212
+ })
213
+ end
214
+
104
215
  end
@@ -0,0 +1,20 @@
1
+
2
+ class Wco::SitemapPath
3
+ include Mongoid::Document
4
+ include Mongoid::Timestamps
5
+ include Mongoid::Paranoia
6
+ store_in collection: 'wco_sitemap_paths'
7
+
8
+ belongs_to :site, class_name: 'Wco::Site'
9
+
10
+ field :path, type: String
11
+ validates :path, presence: true, uniqueness: { scope: :site }
12
+
13
+ field :redirect_to, type: String
14
+ field :selector, type: String
15
+ field :selectors, type: Array, default: []
16
+
17
+ field :status, type: String
18
+
19
+ end
20
+
@@ -10,6 +10,9 @@ class WcoEmail::EmailFilter
10
10
 
11
11
  PAGE_PARAM_NAME = :filters_page
12
12
 
13
+ FIELD_OPTS = [ :subject, :from, :to, :to_and_cc, :body, ]
14
+ MATCHTYPE_OPTS = [ :regex, :exact_insensitive, ]
15
+
13
16
  field :from_regex
14
17
  field :from_exact
15
18
  field :subject_regex
@@ -20,6 +23,10 @@ class WcoEmail::EmailFilter
20
23
  field :skip_from_regex
21
24
  field :skip_to_exact
22
25
 
26
+ has_many :email_filter_conditions
27
+ has_many :email_filter_skip_conditions, class_name: 'WcoEmail::EmailFilterCondition'
28
+ has_and_belongs_to_many :action_tmpls, class_name: 'Wco::OfficeActionTemplate'
29
+
23
30
  belongs_to :tag, class_name: 'Wco::Tag', inverse_of: :email_filters, optional: true
24
31
 
25
32
  KIND_AUTORESPOND_TMPL = 'autorespond-template'
@@ -36,6 +43,7 @@ class WcoEmail::EmailFilter
36
43
  KINDS = [ nil, KIND_AUTORESPOND_TMPL, KIND_AUTORESPOND_EACT, KIND_ADD_TAG, KIND_REMOVE_TAG, KIND_DESTROY_SCHS]
37
44
  field :kind
38
45
 
46
+
39
47
  belongs_to :email_template, class_name: 'WcoEmail::EmailTemplate', optional: true
40
48
  belongs_to :email_action_template, class_name: 'WcoEmail::EmailActionTemplate', optional: true
41
49
 
@@ -0,0 +1,17 @@
1
+
2
+ class WcoEmail::EmailFilterCondition
3
+ include Mongoid::Document
4
+ include Mongoid::Timestamps
5
+ include Mongoid::Paranoia
6
+ store_in collection: 'office_email_filter_conditions'
7
+
8
+ belongs_to :email_filter, inverse_of: :email_filter_conditions
9
+ belongs_to :email_filter_skip, inverse_of: :email_filter_skip_conditions
10
+
11
+ field :field
12
+ field :matchtype
13
+ field :value
14
+
15
+
16
+ end
17
+
@@ -29,7 +29,10 @@ class WcoEmail::Message
29
29
 
30
30
  field :read_at, type: DateTime
31
31
  index({ read_at: -1 })
32
- scope :unread, ->{ where( read_at: nil ) }
32
+ def self.unread
33
+ where( read_at: nil )
34
+ end
35
+ # scope :unread, ->() { where( read_at: nil ) }
33
36
 
34
37
  def part_html_sanitized
35
38
  doc = Nokogiri::HTML part_html
@@ -0,0 +1,257 @@
1
+
2
+ # require 'ish/premium_item'
3
+ require 'ish/utils'
4
+
5
+ class WcoGame::Location
6
+ include Mongoid::Document
7
+ include Mongoid::Timestamps
8
+ # include Ish::PremiumItem
9
+ include Mongoid::Paranoia
10
+ include Wco::Utils
11
+ store_in collection: 'gameui_maps'
12
+
13
+ field :name
14
+
15
+ field :newsitems_page_size, default: 25
16
+
17
+ field :slug
18
+ validates :slug, uniqueness: true, presence: true
19
+
20
+ field :description
21
+
22
+ has_many :markers, :class_name => '::Gameui::Marker', inverse_of: :map
23
+ has_many :from_markers, :class_name => '::Gameui::Marker', inverse_of: :destination
24
+
25
+ has_many :newsitems, inverse_of: :map, order: :created_at.desc
26
+
27
+ # @TODO: remove field, replace with relation. _vp_ 2022-09-13
28
+ field :parent_slug
29
+ belongs_to :parent, class_name: '::Gameui::Map', inverse_of: :childs, optional: true
30
+ has_many :childs, class_name: '::Gameui::Map', inverse_of: :parent
31
+
32
+ has_one :image, class_name: '::Ish::ImageAsset', inverse_of: :location
33
+ belongs_to :creator_profile, class_name: '::Ish::UserProfile', inverse_of: :my_maps
34
+
35
+ has_and_belongs_to_many :bookmarked_profiles, class_name: '::Ish::UserProfile', inverse_of: :bookmarked_location
36
+
37
+ # shareable, nonpublic
38
+ field :is_public, type: Boolean, default: true
39
+ scope :public, ->{ where( is_public: true ) }
40
+ has_and_belongs_to_many :shared_profiles, :class_name => 'Ish::UserProfile', :inverse_of => :shared_locations
41
+
42
+ field :version, type: String, default: '0.0.0'
43
+
44
+ ## @TODO: or self, right? and refactor this, seems N+1. _vp_ 2022-09-13
45
+ field :map_slug
46
+ def map
47
+ ::Gameui::Map.where( slug: map_slug ).first
48
+ end
49
+
50
+ RATED_OPTIONS = [ 'pg-13', 'r', 'nc-17' ]
51
+ field :rated, default: 'pg-13' # 'r', 'nc-17'
52
+
53
+ ## Possible keys: description, map, markers, newsitems,
54
+ field :labels, type: Object, default: <<~AOL
55
+ { "description":"Description", "map":"Map", "markers":"Markers", "newsitems":"Newsitems"
56
+ }
57
+ AOL
58
+
59
+ ## Possible keys:
60
+ ## config.description.collapsible
61
+ field :config, type: Object, default: <<~AOL
62
+ { "map_panel_type": "ThreePanelV1",
63
+ "studio": { "hasFloor": true, "studioLength": 2500, "studioWidth": 2500 }
64
+ }
65
+ AOL
66
+
67
+ # @deprecated, dont use!
68
+ field :img_path
69
+
70
+ ## Not used! See config.map_panel_type instead.
71
+ # MAP_TYPES = [ :map_2d, :map_3d, :map_geospatial, :map_gallery, :map_toc ] ## Mostly not implemented. _vp_ 2022-09-06
72
+ # field :map_type, default: :map_2d
73
+
74
+ ## Make sure to use x,y,z and w,h as appropriate.
75
+ ## @TODO: abstract this into a module
76
+ field :x, type: Float
77
+ field :y, type: Float
78
+ field :z, type: Float
79
+
80
+ ## Make sure to use x,y,z and w,h as appropriate.
81
+ field :w, type: Integer
82
+ validates :w, presence: true
83
+ field :h, type: Integer
84
+ validates :h, presence: true
85
+ # @TODO: this is shared between map and marker, move to a concern.
86
+ before_validation :compute_w_h
87
+ def compute_w_h
88
+ return if !image ## @TODO: test this
89
+
90
+ begin
91
+ geo = Paperclip::Geometry.from_file(Paperclip.io_adapters.for(image.image))
92
+ self.w = geo.width
93
+ self.h = geo.height
94
+ rescue Paperclip::Errors::NotIdentifiedByImageMagickError => e
95
+ puts! e, 'Could not #compute_w_h'
96
+ # @TODO: do something with this
97
+ end
98
+ end
99
+
100
+ ORDERING_TYPE_ALPHABETIC = 'alphabetic'
101
+ ORDERING_TYPE_CUSTOM = 'custom'
102
+ ORDERING_TYPE_TIMESTAMP = 'timestamp'
103
+ ORDERING_TYPES = [ ORDERING_TYPE_ALPHABETIC, ORDERING_TYPE_CUSTOM, ORDERING_TYPE_TIMESTAMP ]
104
+ field :ordering_type, type: String, default: 'custom' # timestamp, alphabetic, custom
105
+ validates :ordering_type, presence: true
106
+
107
+ def self.list conditions = { is_trash: false }
108
+ out = self.order_by( created_at: :desc )
109
+ [[nil, nil]] + out.map { |item| [ item.name, item.id.to_s ] }
110
+ end
111
+
112
+ def breadcrumbs
113
+ out = [{ name: self.name, slug: self.slug, link: false }]
114
+ p = self.parent
115
+ while p
116
+ out.push({ name: p.name, slug: p.slug })
117
+ p = p.parent
118
+ end
119
+ out.reverse
120
+ end
121
+
122
+ ##
123
+ ## @TODO: move the export func, below, to a module. _vp_ 2022-09-20
124
+ ##
125
+
126
+ def empty_export
127
+ return {
128
+ galleries: {},
129
+ image_assets: {},
130
+ maps: {}, markers: {},
131
+ newsitems: {},
132
+ photos: {}, profiles: {},
133
+ reports: {},
134
+ videos: {},
135
+ }
136
+ end
137
+ def self.empty_export; Gameui::Map.new.empty_export; end
138
+
139
+ def empty_export_arr
140
+ return {
141
+ galleries: [],
142
+ image_assets: [],
143
+ maps: [], markers: [],
144
+ newsitems: [],
145
+ photos: [], profiles: [],
146
+ reports: [],
147
+ videos: [],
148
+ }
149
+ end
150
+
151
+ def export_key_to_class
152
+ return {
153
+ galleries: 'Gallery',
154
+ image_assets: 'Ish::ImageAsset',
155
+ maps: 'Gameui::Map',
156
+ markers: 'Gameui::Marker',
157
+ newsitems: 'Newsitem',
158
+ photos: 'Photo',
159
+ profiles: 'Ish::UserProfile',
160
+ reports: 'Report',
161
+ videos: 'Video',
162
+ # 'galleries' => 'Gallery',
163
+ # 'image_assets' => 'Ish::ImageAsset',
164
+ # 'maps' => 'Gameui::Map',
165
+ # 'markers' => 'Gameui::Marker',
166
+ # 'newsitems' => 'Newsitem',
167
+ # 'photos' => 'Photo',
168
+ # 'profiles' => 'Ish::UserProfile',
169
+ # 'reports' => 'Report',
170
+ # 'videos' => 'Video',
171
+ }.with_indifferent_access
172
+ end
173
+ def self.export_key_to_class
174
+ Map.new.export_key_to_class
175
+ end
176
+
177
+ def export_fields
178
+ %w|
179
+ creator_profile_id config
180
+ deleted_at description
181
+ h
182
+ is_public
183
+ labels
184
+ map_slug
185
+ name
186
+ ordering_type
187
+ parent_slug
188
+ rated
189
+ slug
190
+ version
191
+ w
192
+ |
193
+ end
194
+
195
+ ## This is the starting point _vp_ 2022-03-12
196
+ ##
197
+ def export_subtree
198
+ collected = collect(empty_export)
199
+ exportable = empty_export_arr
200
+ collected.map do |k, v|
201
+ if v.present?
202
+ v.map do |id|
203
+ id = id[0]
204
+ item = export_key_to_class[k].constantize.unscoped.find id
205
+ export = item.export
206
+ exportable[k].push( export )
207
+ end
208
+ end
209
+ end
210
+ JSON.pretty_generate exportable
211
+ end
212
+
213
+ def collect export_object
214
+ map = self
215
+ export_object[:maps][map.id.to_s] = map.id.to_s
216
+
217
+ if map.markers.present?
218
+ map.markers.map do |marker|
219
+ id = marker.id.to_s
220
+ if !export_object[:markers][id]
221
+ marker.collect( export_object )
222
+ end
223
+ export_object[:markers][id] = id
224
+ end
225
+ end
226
+
227
+ if map.newsitems.present?
228
+ map.newsitems.map do |newsitem|
229
+ id = newsitem.id.to_s
230
+ export_object[:newsitems][id] = id
231
+ newsitem.collect export_object
232
+ end
233
+ end
234
+
235
+ ## @TODO: maybe implement this later, maybe not. _vp_ 2022-03-12
236
+ # if map.childs.present?
237
+ # export_object[:maps].push( map.childs.map &:id )
238
+ # map.childs.map do |child|
239
+ # child.collect export_object
240
+ # end
241
+ # end
242
+
243
+ if map.creator_profile.present?
244
+ export_object[:profiles][map.creator_profile.id.to_s] = map.creator_profile.id.to_s
245
+ end
246
+
247
+ if map.image.present?
248
+ export_object[:image_assets][map.image.id.to_s] = map.image.id.to_s
249
+ end
250
+
251
+ export_object
252
+ end
253
+
254
+ ## endExport
255
+
256
+
257
+ end
@@ -0,0 +1,9 @@
1
+
2
+ class WcoGame::Marker
3
+ include Mongoid::Document
4
+ include Mongoid::Timestamps
5
+ include Mongoid::Paranoia
6
+ include Wco::Utils
7
+ store_in collection: 'gameui_markers'
8
+
9
+ end
@@ -1,6 +1,9 @@
1
1
  !!!
2
2
  %html
3
3
  %head
4
+ %title #{@page_title} | Wco Core
5
+ %link{ :rel => 'icon', :href => "/favicon_#{ENV['RAILS_ENV']}.gif" }
6
+ %meta{ :name => :viewport, :content => 'width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=2' }
4
7
  %meta{content: "text/html; charset=UTF-8", "http-equiv" => "Content-Type"}
5
8
  %title Wco Models
6
9
 
@@ -7,36 +7,39 @@
7
7
 
8
8
  %i.fa.fa-compress.collapse-expand#collapseHeaderModels
9
9
  Wco Suite
10
- .flex-row
11
- %ul
12
- %li= link_to 'ROOT', '/'
13
- - if defined? wco_email
14
- %li= link_to '/email', '/email'
15
- - if defined? wco_hosting
16
- %li= link_to '/hosting', '/hosting'
17
- - if defined? iro
18
- %li= link_to '/trading', '/trading'
19
-
20
- %ul
21
- %li= render '/wco/invoices/header'
22
- %li= render '/wco/products/header'
23
- %li= render '/wco/tags/header'
24
- %li= render '/wco/logs/header'
25
-
26
- %ul
27
- %li= render '/wco/leadsets/header'
28
- %li= render '/wco/leads/header'
29
- %li= render '/wco/office_action_templates/header'
30
- %li= render '/wco/office_actions/header'
31
- %li= render '/wco/profiles/header'
32
-
33
- %ul
34
- %li= render '/wco/sites/header'
35
- %li= render '/wco/headlines/header'
36
- %li= render '/wco/publishers/header'
37
- %li= render '/wco/galleries/header_mini'
38
- %li= render '/wco/reports/header'
39
- %li= render '/wco/videos/header'
10
+ .W
11
+
12
+ .d-flex.flex-wrap
13
+
14
+ %ul
15
+ %li= link_to 'ROOT', '/'
16
+ - if defined? wco_email
17
+ %li= link_to '/email', '/email'
18
+ - if defined? wco_hosting
19
+ %li= link_to '/hosting', '/hosting'
20
+ - if defined? iro
21
+ %li= link_to '/trading', '/trading'
22
+
23
+ %ul
24
+ %li= render '/wco/invoices/header'
25
+ %li= render '/wco/products/header'
26
+ %li= render '/wco/tags/menuitem'
27
+ %li= render '/wco/logs/header'
28
+
29
+ %ul
30
+ %li= render '/wco/leadsets/header'
31
+ %li= render '/wco/leads/header'
32
+ %li= render '/wco/office_action_templates/header'
33
+ %li= render '/wco/office_actions/header'
34
+ %li= render '/wco/profiles/header'
35
+
36
+ %ul
37
+ %li= render '/wco/sites/header'
38
+ %li= render '/wco/headlines/header'
39
+ %li= render '/wco/publishers/header'
40
+ %li= render '/wco/galleries/header_mini'
41
+ %li= render '/wco/reports/header'
42
+ %li= render '/wco/videos/header'
40
43
 
41
44
 
42
45
  .c
@@ -6,8 +6,9 @@
6
6
  = f.text_field :name
7
7
 
8
8
  .field
9
- = f.label :email
10
- = f.text_field :email
9
+ %label.required Email
10
+ = f.text_field :email, required: true
11
+ .small.gray Required to create a leadset
11
12
 
12
13
  .field
13
14
  = f.label :phone
@@ -19,7 +20,7 @@
19
20
 
20
21
  .field
21
22
  = f.label "Leadset (company)"
22
- = f.select :leadset, options_for_select(@leadsets_list, selected: lead.leadset_id), {}, { class: :select2 }
23
+ = f.select :leadset_id, options_for_select(@leadsets_list, selected: lead.leadset_id), {}, { class: :select2 }
23
24
 
24
25
  -# .field
25
26
  -# %label Rating
@@ -31,10 +32,10 @@
31
32
 
32
33
  .field
33
34
  = f.label "Tags"
34
- = f.select :tags, options_for_select(@tags_list, selected: lead.tag_ids ), {}, { class: :select2, multiple: true }
35
+ = f.select :tag_ids, options_for_select(@tags_list, selected: lead.tag_ids ), {}, { class: :select2, multiple: true }
35
36
 
36
37
  .field
37
- = f.label :photo
38
+ %label Photo
38
39
  = f.file_field :photo
39
40
 
40
41
  .actions
@@ -0,0 +1,16 @@
1
+
2
+ %ul.leads--list
3
+ - leads.each do |lead|
4
+ %li.item
5
+ = image_tag lead.photo.photo.url(:thumb)
6
+ = link_to lead, lead_path(lead)
7
+ = link_to '[~]', edit_lead_path(lead)
8
+
9
+ -# \(#{lead.scheduled_email_actions.length} sch
10
+ -# %span.expand-next [+]
11
+ -# .expand-hide= render 'ish_manager/scheduled_actions/form_mini'
12
+ -# \)
13
+
14
+ - if defined?( wco_email )
15
+ %span.expand-next [reply]
16
+ .expand-hide= render '/wco_email/contexts/form_reply_mini', lead: lead
@@ -39,7 +39,7 @@
39
39
  = link_to '[~]', edit_lead_path( lead )
40
40
  = link_to "#{lead.name} <#{lead.email}>", lead_path( lead )
41
41
  %td
42
- = image_tag lead.photo.url(:thumb) if lead.photo
42
+ = image_tag lead.photo.photo.url(:thumb) if lead.photo
43
43
  %td.company
44
44
  = lead.leadset.company_url
45
45
  %td
@@ -14,4 +14,4 @@
14
14
  (#{@leads.length})
15
15
  = link_to raw("<i class='fa fa-plus-square'></i>"), new_lead_path
16
16
 
17
- = render 'index', leads: @leads, search_path: leads_path
17
+ = render '/wco/leads/table', leads: @leads, search_path: leads_path
@@ -22,16 +22,16 @@
22
22
  %li Address: #{@lead.address}
23
23
  -# - if @lead.comment
24
24
  -# %li Comment: #{raw @lead.comment}
25
- - if @lead.photo
26
- %li
27
- = image_tag Photo.find( @lead.photo_id ).photo.url(:small)
28
25
 
29
26
  .col-md-6
27
+ - if @lead.photo
28
+ = image_tag @lead.photo.photo.url(:thumb2)
29
+
30
30
  %h5 Tags
31
31
  %ul
32
32
  - @lead.tags.each do |tag|
33
33
  %li
34
- = link_to tag.name, tag_path(tag)
34
+ = link_to tag, tag_path(tag)
35
35
 
36
36
  .row
37
37
  .col-md-6.ctxs
@@ -0,0 +1,18 @@
1
+
2
+ .sitemap-paths--form
3
+ = form_for spath do |f|
4
+ = hidden_field_tag :site_id, spath[:site_id] || params[:site_id]
5
+
6
+ .d-flex
7
+ .field
8
+ %label Path
9
+ = f.text_field :path
10
+ .field
11
+ %label redirect_to
12
+ = f.text_field :redirect_to
13
+ .field
14
+ %label selector
15
+ = f.text_field :selector
16
+
17
+ .actions
18
+ = f.submit 'Go'
@@ -0,0 +1,15 @@
1
+
2
+ .sitemap-paths--index
3
+ %table.bordered.data-table
4
+ %thead
5
+ %td Path
6
+ %td Redirect To
7
+ %td Selector
8
+ %td Status
9
+ %tbody
10
+ - spaths.each do |spath|
11
+ %tr
12
+ %td= spath.path
13
+ %td= spath.redirect_to
14
+ %td= spath.selector
15
+ %td= spath.status
@@ -1,8 +1,18 @@
1
1
 
2
- .sites-show.maxwidth
3
- .header
4
- %h5.title
5
- = @site
2
+ .sites-show.padded
3
+ .maxwidth
4
+ .header
5
+ %h5.title
6
+ = @site
6
7
 
7
- = render '/wco/tags/header'
8
- = render '/wco/tags/index', tags: @site.tags
8
+ = render '/wco/tags/header'
9
+ = render '/wco/tags/index', tags: @site.tags
10
+
11
+ %h5.d-flex
12
+ Sitemap Paths&nbsp;
13
+ = link_to '[+]', new_sitemap_path_path( site_id: @site.id )
14
+ &nbsp;
15
+ = button_to 'check', check_sitemap_path( site: @site ), data: { confirm: 'Are you sure?' }
16
+ = render '/wco/sitemap_paths/form', spath: @new_sitemap_path
17
+ -# %hr
18
+ = render '/wco/sitemap_paths/index', spaths: @site.sitemap_paths
@@ -1,7 +1,5 @@
1
1
 
2
- .d-flex
3
- = link_to "Tags (#{Wco::Tag.all.length})", wco.tags_path
4
- .inline-search
5
- = form_tag wco.tags_path, method: :get do
6
- = text_field_tag :q
7
- = link_to '[+]', wco.new_tag_path
2
+ .header
3
+ %h5.title
4
+ Tags (#{Wco::Tag.all.length})&nbsp;
5
+ = link_to '[+]', wco.new_tag_path
@@ -10,4 +10,5 @@
10
10
  <b>N reports:</b> #{tag.reports.length}
11
11
  <b>N videos:</b> #{tag.videos.length}
12
12
  <b>N stubs:</b> #{tag.message_stubs.length}
13
+ <b>N leads:</b> #{tag.leads.length}
13
14
  <b>N logs:</b> #{tag.logs.length}
@@ -0,0 +1,9 @@
1
+
2
+ .d-flex
3
+ = link_to "Tags (#{Wco::Tag.all.length})", wco.tags_path
4
+ &nbsp;
5
+ .inline-search
6
+ = form_tag wco.tags_path, method: :get do
7
+ = text_field_tag :q
8
+ &nbsp;
9
+ = link_to '[+]', wco.new_tag_path
@@ -1,7 +1,7 @@
1
1
 
2
2
  .tags-index.maxwidth
3
3
  .header
4
- %h5.title Tags
4
+ %h5.title Tags (#{@tags.length})
5
5
 
6
6
  = render 'index', tags: @tags
7
7
 
@@ -14,12 +14,17 @@
14
14
  <b>Message Stubs (#{@tag.message_stubs.length}):&nbsp;</b>
15
15
  = render '/wco_email/message_stubs/index', stubs: @tag.message_stubs
16
16
 
17
+ %li.d-flex
18
+ <b>Galleries (#{@galleries.length}):&nbsp;</b>
19
+ = render 'wco/galleries/index', galleries: @galleries, config: { skip_tags: true }
17
20
  %li.d-flex
18
21
  <b>Headlines (#{@tag.headlines.length}):&nbsp;</b>
19
22
  = render '/wco/headlines/index', headlines: @tag.headlines
23
+
20
24
  %li.d-flex
21
- <b>Galleries (#{@galleries.length}):&nbsp;</b>
22
- = render 'wco/galleries/index', galleries: @galleries, config: { skip_tags: true }
25
+ <b>Leads (#{@tag.leads.length}):&nbsp;</b>
26
+ = render 'wco/leads/list', leads: @tag.leads
27
+
23
28
  %li.d-flex
24
29
  <b>Reports (#{@reports.length}):&nbsp;</b>
25
30
  = render 'wco/reports/index', reports: @reports, config: { skip_tags: true }
data/config/routes.rb CHANGED
@@ -54,7 +54,9 @@ Wco::Engine.routes.draw do
54
54
  get 'reports/deleted', to: 'reports#index', as: :deleted_reports, defaults: { deleted: true }
55
55
  resources :reports
56
56
 
57
+ post 'sites/:id/check_sitemap', to: 'sites#check_sitemap', as: :check_sitemap
57
58
  resources :sites
59
+ resources :sitemap_paths
58
60
  resources :subscriptions
59
61
 
60
62
  delete 'tags/remove/:id/from/:resource/:resource_id', to: 'tags#remove_from', as: :remove_tag_from
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wco_models
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0.154
4
+ version: 3.1.0.157
5
5
  platform: ruby
6
6
  authors:
7
7
  - Victor Pudeyev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-04-13 00:00:00.000000000 Z
11
+ date: 2024-05-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-s3
@@ -455,6 +455,7 @@ files:
455
455
  - app/models/wco/publisher.rb
456
456
  - app/models/wco/report.rb
457
457
  - app/models/wco/site.rb
458
+ - app/models/wco/sitemap_path.rb
458
459
  - app/models/wco/subscription.rb
459
460
  - app/models/wco/tag.rb
460
461
  - app/models/wco/utils.rb
@@ -466,11 +467,14 @@ files:
466
467
  - app/models/wco_email/email_action_template.rb
467
468
  - app/models/wco_email/email_action_template_tie.rb
468
469
  - app/models/wco_email/email_filter.rb
470
+ - app/models/wco_email/email_filter_condition.rb
469
471
  - app/models/wco_email/email_template.rb
470
472
  - app/models/wco_email/message.rb
471
473
  - app/models/wco_email/message_stub.rb
472
474
  - app/models/wco_email/obfuscated_redirect.rb
473
475
  - app/models/wco_email/unsubscribe.rb
476
+ - app/models/wco_game/location.rb
477
+ - app/models/wco_game/marker.rb
474
478
  - app/models/wco_hosting/appliance.rb
475
479
  - app/models/wco_hosting/appliance_tmpl.rb
476
480
  - app/models/wco_hosting/domain.rb
@@ -527,8 +531,8 @@ files:
527
531
  - app/views/wco/leads/_form.haml
528
532
  - app/views/wco/leads/_form_import.haml
529
533
  - app/views/wco/leads/_header.haml
530
- - app/views/wco/leads/_index.haml
531
- - app/views/wco/leads/_index_rows.haml
534
+ - app/views/wco/leads/_list.haml
535
+ - app/views/wco/leads/_table.haml
532
536
  - app/views/wco/leads/edit.haml
533
537
  - app/views/wco/leads/index.haml
534
538
  - app/views/wco/leads/new.haml
@@ -559,7 +563,7 @@ files:
559
563
  - app/views/wco/office_actions/index.haml
560
564
  - app/views/wco/office_actions/new.haml
561
565
  - app/views/wco/office_actions/show.haml
562
- - app/views/wco/photos/_form.haml
566
+ - app/views/wco/photos/_form.haml-trash
563
567
  - app/views/wco/photos/_index_thumbs.haml
564
568
  - app/views/wco/photos/_meta.haml
565
569
  - app/views/wco/photos/_meta_manager.haml
@@ -597,6 +601,8 @@ files:
597
601
  - app/views/wco/reports/index_table.haml
598
602
  - app/views/wco/reports/new.haml
599
603
  - app/views/wco/reports/show.haml
604
+ - app/views/wco/sitemap_paths/_form.haml
605
+ - app/views/wco/sitemap_paths/_index.haml
600
606
  - app/views/wco/sites/_form.haml
601
607
  - app/views/wco/sites/_header.haml
602
608
  - app/views/wco/sites/edit.haml
@@ -608,6 +614,7 @@ files:
608
614
  - app/views/wco/tags/_index.haml
609
615
  - app/views/wco/tags/_index_chips.haml
610
616
  - app/views/wco/tags/_list_chips.haml
617
+ - app/views/wco/tags/_menuitem.haml
611
618
  - app/views/wco/tags/edit.haml
612
619
  - app/views/wco/tags/index.haml
613
620
  - app/views/wco/tags/new.haml
@@ -1,11 +0,0 @@
1
-
2
- .leads--index-rows
3
- - leads.each do |lead|
4
- .item
5
- = link_to lead.email, lead_path(lead)
6
- \(#{lead.scheduled_email_actions.length} sch
7
- %span.expand-next [+]
8
- .expand-hide= render 'ish_manager/scheduled_actions/form_mini'
9
- \)
10
- %span.expand-next [reply]
11
- .expand-hide= render 'ish_manager/email_contexts/form_reply', lead: lead