biovision-regions 0.1.180120
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +28 -0
- data/Rakefile +26 -0
- data/app/assets/config/biovision_regions_manifest.js +2 -0
- data/app/assets/images/biovision/regions/placeholders/region_image.svg +1 -0
- data/app/assets/javascripts/biovision/regions/application.js +13 -0
- data/app/assets/stylesheets/biovision/regions/regions.scss +25 -0
- data/app/controllers/admin/regions_controller.rb +29 -0
- data/app/controllers/biovision/regions/application_controller.rb +7 -0
- data/app/controllers/regions_controller.rb +73 -0
- data/app/helpers/biovision/regions/application_helper.rb +6 -0
- data/app/helpers/biovision_regions_helper.rb +22 -0
- data/app/jobs/biovision/regions/application_job.rb +6 -0
- data/app/mailers/biovision/regions/application_mailer.rb +8 -0
- data/app/models/application_record.rb +3 -0
- data/app/models/biovision/regions/application_record.rb +7 -0
- data/app/models/central_region.rb +53 -0
- data/app/models/country.rb +61 -0
- data/app/models/region.rb +141 -0
- data/app/uploaders/header_image_uploader.rb +50 -0
- data/app/uploaders/region_image_uploader.rb +53 -0
- data/app/views/admin/admin/privileges/entity/_region.html.erb +12 -0
- data/app/views/admin/admin/privileges/regions.jbuilder +10 -0
- data/app/views/admin/index/dashboard/_biovision_regions.html.erb +8 -0
- data/app/views/admin/regions/_nav_item.html.erb +2 -0
- data/app/views/admin/regions/entity/_in_list.html.erb +20 -0
- data/app/views/admin/regions/index.html.erb +22 -0
- data/app/views/admin/regions/show.html.erb +95 -0
- data/app/views/layouts/biovision/regions/application.html.erb +14 -0
- data/app/views/regions/_form.html.erb +73 -0
- data/app/views/regions/edit.html.erb +20 -0
- data/app/views/regions/new.html.erb +17 -0
- data/config/locales/regions-en.yml +73 -0
- data/config/locales/regions-ru.yml +73 -0
- data/config/routes.rb +17 -0
- data/db/migrate/20180120000000_create_countries.rb +41 -0
- data/db/migrate/20180120000005_create_regions.rb +36 -0
- data/lib/biovision/regions/decorators/controllers/admin/privileges_controller_decorator.rb +7 -0
- data/lib/biovision/regions/decorators/models/user_decorator.rb +3 -0
- data/lib/biovision/regions/decorators/models/user_privilege_decorator.rb +3 -0
- data/lib/biovision/regions/engine.rb +24 -0
- data/lib/biovision/regions/privilege_methods.rb +53 -0
- data/lib/biovision/regions/version.rb +5 -0
- data/lib/biovision/regions.rb +7 -0
- data/lib/tasks/biovision/regions_tasks.rake +4 -0
- data/lib/tasks/regions.rake +67 -0
- metadata +244 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 56e46f0c1c879478cd508c894658d3e4b0c530dc4a73007ab6261bbd5dab7d12
|
4
|
+
data.tar.gz: fffd17eb6cb04b86a2438cea3fa951067213ec315eba598ec85aca62af0cc601
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4f45f1333cad9b829a4e0e687afcb36c112533eedf231d027210b9f7fd67104fcb2cb100712716af5a4942dfe4fcbc7c90fedfc633e7a105850e1b4bece17a57
|
7
|
+
data.tar.gz: 005ae18487f205491ba677f7163fdd1d34d317c0ce8ed162e3ee0648026742aa2fd65ad2a33d78529bf853fe56f1cf35635136bea95665237d52be8a1b9882df
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2018 Maxim Khan-Magomedov
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# Biovision::Regions
|
2
|
+
Short description and motivation.
|
3
|
+
|
4
|
+
## Usage
|
5
|
+
How to use my plugin.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem 'biovision-regions'
|
12
|
+
```
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
```bash
|
16
|
+
$ bundle
|
17
|
+
```
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
```bash
|
21
|
+
$ gem install biovision-regions
|
22
|
+
```
|
23
|
+
|
24
|
+
## Contributing
|
25
|
+
Contribution directions go here.
|
26
|
+
|
27
|
+
## License
|
28
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'Biovision::Regions'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
APP_RAKEFILE = File.expand_path("../spec/test_app/Rakefile", __FILE__)
|
18
|
+
load 'rails/tasks/engine.rake'
|
19
|
+
|
20
|
+
|
21
|
+
load 'rails/tasks/statistics.rake'
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
require 'bundler/gem_tasks'
|
26
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
<?xml version="1.0" ?><svg height="24" version="1.1" width="24" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><g transform="translate(0 -1028.4)"><path d="m3 1031.4v10c0 4.2 3.6322 8 9 10 5.368-2 9-5.8 9-10v-10h-18z" fill="#7f8c8d"/><path d="m3 1030.4v10c0 4.2 3.6322 8 9 10 5.368-2 9-5.8 9-10v-10h-18z" fill="#bdc3c7"/><path d="m3 1030.4v10c0 4.2 3.6322 8 9 10v-20h-9z" fill="#95a5a6"/><path d="m5 1032.4v8c0 3.4 2.8251 6.4 7 8 4.175-1.6 7-4.6 7-8v-8h-14z" fill="#ecf0f1"/><path d="m5 1040.4c0 3.4 2.8251 6.4 7 8v-8h-7z" fill="#2980b9"/><rect fill="#3498db" height="8" transform="translate(0 1028.4)" width="7" x="12" y="4"/><rect fill="#bdc3c7" height="8" transform="translate(0 1028.4)" width="7" x="5" y="4"/></g></svg>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// compiled file. JavaScript code in this file should be added after the last require_* statement.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require_tree .
|
@@ -0,0 +1,25 @@
|
|
1
|
+
$border-primary: .1rem solid #777 !default;
|
2
|
+
|
3
|
+
form {
|
4
|
+
#region-image {
|
5
|
+
img {
|
6
|
+
border: $border-primary;
|
7
|
+
max-height: 11rem;
|
8
|
+
width: 11rem;
|
9
|
+
}
|
10
|
+
}
|
11
|
+
}
|
12
|
+
|
13
|
+
.privileges {
|
14
|
+
&.regions {
|
15
|
+
margin: 0 0 0 1.2rem;
|
16
|
+
padding: 0;
|
17
|
+
border: none;
|
18
|
+
|
19
|
+
> li {
|
20
|
+
list-style: none;
|
21
|
+
margin: 0;
|
22
|
+
padding: 0;
|
23
|
+
}
|
24
|
+
}
|
25
|
+
}
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class Admin::RegionsController < AdminController
|
2
|
+
include ToggleableEntity
|
3
|
+
include LockableEntity
|
4
|
+
include EntityPriority
|
5
|
+
|
6
|
+
before_action :set_entity, except: [:index]
|
7
|
+
|
8
|
+
# get /admin/regions
|
9
|
+
def index
|
10
|
+
@collection = Region.for_tree
|
11
|
+
end
|
12
|
+
|
13
|
+
# get /admin/regions/:id
|
14
|
+
def show
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def restrict_access
|
20
|
+
require_privilege_group :region_managers
|
21
|
+
end
|
22
|
+
|
23
|
+
def set_entity
|
24
|
+
@entity = Region.find_by(id: params[:id])
|
25
|
+
if @entity.nil?
|
26
|
+
handle_http_404("Cannot find region #{params[:id]}")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
class RegionsController < AdminController
|
2
|
+
before_action :set_entity, only: [:edit, :update, :destroy]
|
3
|
+
before_action :restrict_editing, only: [:edit, :update, :destroy]
|
4
|
+
|
5
|
+
# post /regions
|
6
|
+
def create
|
7
|
+
@entity = Region.new(creation_parameters)
|
8
|
+
if @entity.save
|
9
|
+
cache_relatives
|
10
|
+
redirect_to admin_region_path(@entity)
|
11
|
+
else
|
12
|
+
render :new, status: :bad_request
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# get /regions/:id/edit
|
17
|
+
def edit
|
18
|
+
end
|
19
|
+
|
20
|
+
# patch /regions/:id
|
21
|
+
def update
|
22
|
+
if @entity.update(entity_parameters)
|
23
|
+
cache_relatives
|
24
|
+
redirect_to admin_region_path(@entity), notice: t('regions.update.success')
|
25
|
+
else
|
26
|
+
render :edit, status: :bad_request
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# delete /post_categories/:id
|
31
|
+
def destroy
|
32
|
+
if @entity.destroy
|
33
|
+
flash[:notice] = t('regions.destroy.success')
|
34
|
+
end
|
35
|
+
redirect_to admin_regions_path
|
36
|
+
end
|
37
|
+
|
38
|
+
protected
|
39
|
+
|
40
|
+
def restrict_access
|
41
|
+
require_privilege_group :region_managers
|
42
|
+
end
|
43
|
+
|
44
|
+
def set_entity
|
45
|
+
@entity = Region.find_by(id: params[:id])
|
46
|
+
if @entity.nil?
|
47
|
+
handle_http_404('Cannot find region')
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def restrict_editing
|
52
|
+
if @entity.locked? || !@entity.editable_by?(current_user)
|
53
|
+
redirect_to admin_region_path(@entity.id), alert: t('regions.edit.forbidden')
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def entity_parameters
|
58
|
+
params.require(:region).permit(Region.entity_parameters)
|
59
|
+
end
|
60
|
+
|
61
|
+
def creation_parameters
|
62
|
+
params.require(:region).permit(Region.creation_parameters)
|
63
|
+
end
|
64
|
+
|
65
|
+
def cache_relatives
|
66
|
+
@entity.cache_parents!
|
67
|
+
unless @entity.parent.blank?
|
68
|
+
parent = @entity.parent
|
69
|
+
parent.cache_children!
|
70
|
+
parent.save
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module BiovisionRegionsHelper
|
2
|
+
# @param [Region] entity
|
3
|
+
def admin_region_link(entity)
|
4
|
+
link_to(entity.name, admin_region_path(entity.id))
|
5
|
+
end
|
6
|
+
|
7
|
+
# @param [Region] entity
|
8
|
+
def region_image_preview(entity)
|
9
|
+
unless entity.image.blank?
|
10
|
+
versions = "#{entity.image.preview_2x.url} 2x"
|
11
|
+
image_tag(entity.image.preview.url, alt: entity.name, srcset: versions)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# @param [Region] entity
|
16
|
+
def region_image_medium(entity)
|
17
|
+
unless entity.image.blank?
|
18
|
+
versions = "#{entity.image.medium_2x.url} 2x"
|
19
|
+
image_tag(entity.image.medium.url, alt: entity.name, srcset: versions)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
class CentralRegion
|
2
|
+
def id
|
3
|
+
nil
|
4
|
+
end
|
5
|
+
|
6
|
+
def name
|
7
|
+
I18n.t('activerecord.attributes.central_region.name')
|
8
|
+
end
|
9
|
+
|
10
|
+
def short_name
|
11
|
+
I18n.t('activerecord.attributes.central_region.short_name')
|
12
|
+
end
|
13
|
+
|
14
|
+
def locative
|
15
|
+
I18n.t('activerecord.attributes.central_region.locative')
|
16
|
+
end
|
17
|
+
|
18
|
+
def slug
|
19
|
+
''
|
20
|
+
end
|
21
|
+
|
22
|
+
def long_slug
|
23
|
+
''
|
24
|
+
end
|
25
|
+
|
26
|
+
def image
|
27
|
+
nil
|
28
|
+
end
|
29
|
+
|
30
|
+
def header_image
|
31
|
+
nil
|
32
|
+
end
|
33
|
+
|
34
|
+
def parents
|
35
|
+
[]
|
36
|
+
end
|
37
|
+
|
38
|
+
def parent
|
39
|
+
nil
|
40
|
+
end
|
41
|
+
|
42
|
+
def parent_id
|
43
|
+
nil
|
44
|
+
end
|
45
|
+
|
46
|
+
def child_regions
|
47
|
+
[]
|
48
|
+
end
|
49
|
+
|
50
|
+
def subbranch_ids
|
51
|
+
[]
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
class Country < ApplicationRecord
|
2
|
+
include RequiredUniqueName
|
3
|
+
include Toggleable
|
4
|
+
|
5
|
+
NAME_LIMIT = 50
|
6
|
+
SLUG_LIMIT = 50
|
7
|
+
SLUG_PATTERN = /\A[a-z][-a-z_]*[a-z]\z/
|
8
|
+
PRIORITY_RANGE = (1..999)
|
9
|
+
|
10
|
+
toggleable :visible
|
11
|
+
|
12
|
+
has_many :regions, dependent: :nullify
|
13
|
+
|
14
|
+
after_initialize :set_next_priority
|
15
|
+
before_validation :normalize_priority
|
16
|
+
|
17
|
+
validates_presence_of :name, :short_name, :locative, :slug
|
18
|
+
validates_length_of :name, maximum: NAME_LIMIT
|
19
|
+
validates_length_of :short_name, maximum: NAME_LIMIT
|
20
|
+
validates_length_of :locative, maximum: NAME_LIMIT
|
21
|
+
validates_length_of :slug, maximum: SLUG_LIMIT
|
22
|
+
validates_format_of :slug, with: SLUG_PATTERN
|
23
|
+
|
24
|
+
scope :ordered_by_priority, -> { order 'priority asc, name asc' }
|
25
|
+
scope :visible, -> { where(visible: true) }
|
26
|
+
scope :list_for_visitors, -> { visible.ordered_by_priority }
|
27
|
+
|
28
|
+
def self.page_for_administration
|
29
|
+
ordered_by_priority
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.entity_parameters
|
33
|
+
%i(visible priority name short_name locative slug)
|
34
|
+
end
|
35
|
+
|
36
|
+
# @param [Integer] delta
|
37
|
+
def change_priority(delta)
|
38
|
+
new_priority = priority + delta
|
39
|
+
criteria = { priority: new_priority }
|
40
|
+
adjacent = self.class.find_by(criteria)
|
41
|
+
if adjacent.is_a?(self.class) && (adjacent.id != id)
|
42
|
+
adjacent.update!(priority: priority)
|
43
|
+
end
|
44
|
+
self.update(priority: new_priority)
|
45
|
+
|
46
|
+
self.class.ordered_by_priority.map { |e| [e.id, e.priority] }.to_h
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def set_next_priority
|
52
|
+
if id.nil? && priority == 1
|
53
|
+
self.priority = self.class.maximum(:priority).to_i + 1
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def normalize_priority
|
58
|
+
self.priority = PRIORITY_RANGE.first if priority < PRIORITY_RANGE.first
|
59
|
+
self.priority = PRIORITY_RANGE.last if priority > PRIORITY_RANGE.last
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
class Region < ApplicationRecord
|
2
|
+
include Toggleable
|
3
|
+
|
4
|
+
SLUG_PATTERN = /\A[a-z0-9](?:[a-z0-9\-]{0,61}[a-z0-9])?\z/
|
5
|
+
PER_PAGE = 20
|
6
|
+
NAME_LIMIT = 70
|
7
|
+
SLUG_LIMIT = 63
|
8
|
+
PRIORITY_RANGE = (1..32767)
|
9
|
+
|
10
|
+
toggleable :visible
|
11
|
+
|
12
|
+
belongs_ro :country, optional: true, counter_cache: true
|
13
|
+
belongs_to :parent, class_name: Region.to_s, optional: true, touch: true
|
14
|
+
has_many :child_regions, class_name: Region.to_s, foreign_key: :parent_id
|
15
|
+
has_many :users, dependent: :nullify
|
16
|
+
|
17
|
+
mount_uploader :image, RegionImageUploader
|
18
|
+
mount_uploader :header_image, HeaderImageUploader
|
19
|
+
|
20
|
+
before_validation { self.slug = slug.to_s.downcase.strip }
|
21
|
+
before_validation :normalize_priority
|
22
|
+
before_save { self.children_cache.uniq! }
|
23
|
+
before_save :generate_long_slug
|
24
|
+
after_save { parent.cache_children! unless parent.nil? }
|
25
|
+
after_create :cache_parents!
|
26
|
+
|
27
|
+
validates_presence_of :name, :slug
|
28
|
+
validates_uniqueness_of :name, :slug, scope: [:parent_id]
|
29
|
+
validates_length_of :name, maximum: NAME_LIMIT
|
30
|
+
validates_length_of :slug, maximum: SLUG_LIMIT
|
31
|
+
validates_format_of :slug, with: SLUG_PATTERN
|
32
|
+
|
33
|
+
scope :ordered_by_priority, -> { order 'priority asc, name asc' }
|
34
|
+
scope :ordered_by_slug, -> { order('slug asc') }
|
35
|
+
scope :ordered_by_name, -> { order('name asc') }
|
36
|
+
scope :visible, -> { where(visible: true) }
|
37
|
+
scope :for_tree, ->(country_id = nil, parent_id = nil) { where(country_id: country_id, parent_id: parent_id).ordered_by_priority }
|
38
|
+
scope :siblings, ->(item) { where(country_id: item.country_id, parent_id: item.parent_id) }
|
39
|
+
|
40
|
+
# @param [Integer] page
|
41
|
+
def self.page_for_administration(page = 1)
|
42
|
+
ordered_by_name.page(page).per(PER_PAGE)
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.entity_parameters
|
46
|
+
%i(name short_name locative slug visible image header_image latitude longitude)
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.creation_parameters
|
50
|
+
entity_parameters + %i(country_id parent_id)
|
51
|
+
end
|
52
|
+
|
53
|
+
# @param [User] user
|
54
|
+
def editable_by?(user)
|
55
|
+
chief = UserPrivilege.user_has_privilege?(user, :chief_region_manager)
|
56
|
+
manager = UserPrivilege.user_has_privilege?(user, :region_manager, self)
|
57
|
+
chief || manager
|
58
|
+
end
|
59
|
+
|
60
|
+
def parents
|
61
|
+
return [] if parents_cache.blank?
|
62
|
+
Region.where(id: parent_ids).order('id asc')
|
63
|
+
end
|
64
|
+
|
65
|
+
def parent_ids
|
66
|
+
parents_cache.split(',').compact
|
67
|
+
end
|
68
|
+
|
69
|
+
# @return [Array<Integer>]
|
70
|
+
def branch_ids
|
71
|
+
parents_cache.split(',').map(&:to_i).reject { |i| i < 1 }.uniq + [id]
|
72
|
+
end
|
73
|
+
|
74
|
+
# @return [Array<Integer>]
|
75
|
+
def subbranch_ids
|
76
|
+
[id] + children_cache
|
77
|
+
end
|
78
|
+
|
79
|
+
def depth
|
80
|
+
parent_ids.count
|
81
|
+
end
|
82
|
+
|
83
|
+
def long_name
|
84
|
+
return name if parents.blank?
|
85
|
+
"#{parents.map(&:name).join('/')}/#{name}"
|
86
|
+
end
|
87
|
+
|
88
|
+
def branch_name
|
89
|
+
return short_name if parents.blank?
|
90
|
+
"#{parents.map(&:short_name).join('/')}/#{short_name}"
|
91
|
+
end
|
92
|
+
|
93
|
+
def cache_parents!
|
94
|
+
return if parent.nil?
|
95
|
+
self.parents_cache = "#{parent.parents_cache},#{parent_id}".gsub(/\A,/, '')
|
96
|
+
save!
|
97
|
+
end
|
98
|
+
|
99
|
+
def cache_children!
|
100
|
+
child_regions.order('id asc').each do |child|
|
101
|
+
self.children_cache += [child.id] + child.children_cache
|
102
|
+
end
|
103
|
+
save!
|
104
|
+
parent.cache_children! unless parent.nil?
|
105
|
+
end
|
106
|
+
|
107
|
+
# @param [Integer] delta
|
108
|
+
def change_priority(delta)
|
109
|
+
new_priority = priority + delta
|
110
|
+
criteria = { country_id: county_id, parent_id: parent_id, priority: new_priority }
|
111
|
+
adjacent = self.class.find_by(criteria)
|
112
|
+
if adjacent.is_a?(self.class) && (adjacent.id != id)
|
113
|
+
adjacent.update!(priority: priority)
|
114
|
+
end
|
115
|
+
self.update(priority: new_priority)
|
116
|
+
|
117
|
+
self.class.for_tree(country_id, parent_id).map { |e| [e.id, e.priority] }.to_h
|
118
|
+
end
|
119
|
+
|
120
|
+
private
|
121
|
+
|
122
|
+
def set_next_priority
|
123
|
+
if id.nil? && priority == 1
|
124
|
+
self.priority = self.class.siblings(self).maximum(:priority).to_i + 1
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def normalize_priority
|
129
|
+
self.priority = PRIORITY_RANGE.first if priority < PRIORITY_RANGE.first
|
130
|
+
self.priority = PRIORITY_RANGE.last if priority > PRIORITY_RANGE.last
|
131
|
+
end
|
132
|
+
|
133
|
+
def generate_long_slug
|
134
|
+
if parents_cache.blank?
|
135
|
+
self.long_slug = slug
|
136
|
+
else
|
137
|
+
slugs = Region.where(id: parent_ids).order('id asc').pluck(:slug) + [slug]
|
138
|
+
self.long_slug = slugs.join('-')
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
class HeaderImageUploader < CarrierWave::Uploader::Base
|
2
|
+
include CarrierWave::MiniMagick
|
3
|
+
include CarrierWave::BombShelter
|
4
|
+
|
5
|
+
storage :file
|
6
|
+
|
7
|
+
def max_pixel_dimensions
|
8
|
+
[4000, 4000]
|
9
|
+
end
|
10
|
+
|
11
|
+
# Override the directory where uploaded files will be stored.
|
12
|
+
# This is a sensible default for uploaders that are meant to be mounted:
|
13
|
+
def store_dir
|
14
|
+
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
|
15
|
+
end
|
16
|
+
|
17
|
+
# Provide a default URL as a default if there hasn't been a file uploaded:
|
18
|
+
# def default_url
|
19
|
+
# # For Rails 3.1+ asset pipeline compatibility:
|
20
|
+
# # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
|
21
|
+
#
|
22
|
+
# "/images/fallback/" + [version_name, "default.png"].compact.join('_')
|
23
|
+
# end
|
24
|
+
|
25
|
+
resize_to_limit 1000, 1000
|
26
|
+
|
27
|
+
version :medium do
|
28
|
+
resize_to_fit 500, 500
|
29
|
+
end
|
30
|
+
|
31
|
+
version :preview_2x, from_version: :medium do
|
32
|
+
resize_to_fit 160, 160
|
33
|
+
end
|
34
|
+
|
35
|
+
version :preview, from_version: :preview_2x do
|
36
|
+
resize_to_fit 80, 80
|
37
|
+
end
|
38
|
+
|
39
|
+
# Add a white list of extensions which are allowed to be uploaded.
|
40
|
+
# For images you might use something like this:
|
41
|
+
def extension_whitelist
|
42
|
+
%w(jpg jpeg png)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Override the filename of the uploaded files:
|
46
|
+
# Avoid using model.id or version_name here, see uploader/store.rb for details.
|
47
|
+
# def filename
|
48
|
+
# "something.jpg" if original_filename
|
49
|
+
# end
|
50
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
class RegionImageUploader < CarrierWave::Uploader::Base
|
2
|
+
include CarrierWave::MiniMagick
|
3
|
+
include CarrierWave::BombShelter
|
4
|
+
|
5
|
+
def max_pixel_dimensions
|
6
|
+
[2000, 2000]
|
7
|
+
end
|
8
|
+
|
9
|
+
storage :file
|
10
|
+
|
11
|
+
# Override the directory where uploaded files will be stored.
|
12
|
+
# This is a sensible default for uploaders that are meant to be mounted:
|
13
|
+
def store_dir
|
14
|
+
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
|
15
|
+
end
|
16
|
+
|
17
|
+
# Provide a default URL as a default if there hasn't been a file uploaded:
|
18
|
+
# def default_url
|
19
|
+
# # For Rails 3.1+ asset pipeline compatibility:
|
20
|
+
# # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
|
21
|
+
#
|
22
|
+
# "/images/fallback/" + [version_name, "default.png"].compact.join('_')
|
23
|
+
# end
|
24
|
+
|
25
|
+
version :header_2x do
|
26
|
+
resize_to_fit 220, 220
|
27
|
+
end
|
28
|
+
|
29
|
+
version :header, from_version: :header_2x do
|
30
|
+
resize_to_fit 110, 110
|
31
|
+
end
|
32
|
+
|
33
|
+
version :preview_2x, from_version: :header_2x do
|
34
|
+
resize_to_fit 160, 160
|
35
|
+
end
|
36
|
+
|
37
|
+
version :preview, from_version: :preview_2x do
|
38
|
+
resize_to_fit 80, 80
|
39
|
+
end
|
40
|
+
|
41
|
+
# Add a white list of extensions which are allowed to be uploaded.
|
42
|
+
# For images you might use something like this:
|
43
|
+
def extension_whitelist
|
44
|
+
%w(jpg jpeg png)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Override the filename of the uploaded files:
|
48
|
+
# Avoid using model.id or version_name here, see uploader/store.rb for details.
|
49
|
+
# def filename
|
50
|
+
# "something.jpg" if original_filename
|
51
|
+
# end
|
52
|
+
|
53
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<div>
|
2
|
+
<% element_id = "user_privilege_#{privilege.id}_#{region.id}" %>
|
3
|
+
<%= check_box_tag element_id, region.id, false, class: 'privilege-adder' %>
|
4
|
+
<%= label_tag element_id, region.name %>
|
5
|
+
</div>
|
6
|
+
<% if region.children_cache.any? %>
|
7
|
+
<ul class="regions" data-url="<%= regions_admin_privilege_path(privilege.id, parent_id: region.id, user_id: user.id) %>">
|
8
|
+
<li>
|
9
|
+
<button class="add_regions" type="button"><%= t('.deeper_level') %></button>
|
10
|
+
</li>
|
11
|
+
</ul>
|
12
|
+
<% end %>
|