c80_map_floors 0.1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.travis.yml +3 -0
  4. data/CODE_OF_CONDUCT.md +13 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +67 -0
  8. data/Rakefile +1 -0
  9. data/app/admin/c80_map_floors/floors.rb +57 -0
  10. data/app/admin/c80_map_floors/map_buildings.rb +49 -0
  11. data/app/admin/c80_map_floors/settings.rb +32 -0
  12. data/app/assets/javascripts/buttons/admin_buttons/button_area_link.js +91 -0
  13. data/app/assets/javascripts/buttons/admin_buttons/button_building_link.js +91 -0
  14. data/app/assets/javascripts/buttons/admin_buttons/button_cancel_create.js +21 -0
  15. data/app/assets/javascripts/buttons/admin_buttons/button_cancel_remove.js +23 -0
  16. data/app/assets/javascripts/buttons/admin_buttons/button_complete_create.js +22 -0
  17. data/app/assets/javascripts/buttons/admin_buttons/button_edit.js +96 -0
  18. data/app/assets/javascripts/buttons/admin_buttons/button_new.js +46 -0
  19. data/app/assets/javascripts/buttons/admin_buttons/button_remove.js +23 -0
  20. data/app/assets/javascripts/buttons/admin_buttons/button_save.js +111 -0
  21. data/app/assets/javascripts/buttons/button_back_to_map.js +84 -0
  22. data/app/assets/javascripts/buttons/zoom_buttons.js +78 -0
  23. data/app/assets/javascripts/c80_map_floors.js.coffee +23 -0
  24. data/app/assets/javascripts/events/app_event.js +15 -0
  25. data/app/assets/javascripts/map_objects/area.js +251 -0
  26. data/app/assets/javascripts/map_objects/building.js +294 -0
  27. data/app/assets/javascripts/map_objects/dot.js +14 -0
  28. data/app/assets/javascripts/map_objects/floor.js +10 -0
  29. data/app/assets/javascripts/src/main.js +1421 -0
  30. data/app/assets/javascripts/src/state_controller.js +322 -0
  31. data/app/assets/javascripts/src/utils/map_utils.js +23 -0
  32. data/app/assets/javascripts/src/utils/opacity_buttons_utils.js +15 -0
  33. data/app/assets/javascripts/src/utils/utils.js +140 -0
  34. data/app/assets/javascripts/svg_elements/area_label.js +25 -0
  35. data/app/assets/javascripts/svg_elements/building_label.js +65 -0
  36. data/app/assets/javascripts/svg_elements/helper.js +36 -0
  37. data/app/assets/javascripts/svg_elements/polygon.js +194 -0
  38. data/app/assets/javascripts/view/save_preloader.js +30 -0
  39. data/app/assets/stylesheets/c80_map_floors.scss +4 -0
  40. data/app/assets/stylesheets/map.scss +1464 -0
  41. data/app/assets/stylesheets/view/buttons/area_order_button.scss +16 -0
  42. data/app/assets/stylesheets/view/buttons/back_to_map_button.scss +28 -0
  43. data/app/assets/stylesheets/view/elems/building_info.scss +54 -0
  44. data/app/assets/stylesheets/view/elems/free_areas_label.scss +116 -0
  45. data/app/assets/stylesheets/view/elems/map_objects/map_object_image_bg.scss +10 -0
  46. data/app/assets/stylesheets/view/modal_window.scss +13 -0
  47. data/app/assets/stylesheets/view/save_preloader.scss +206 -0
  48. data/app/controllers/c80_map_floors/ajax_controller.rb +65 -0
  49. data/app/controllers/c80_map_floors/application_controller.rb +6 -0
  50. data/app/controllers/c80_map_floors/map_ajax_controller.rb +70 -0
  51. data/app/helpers/c80_map_floors/application_helper.rb +28 -0
  52. data/app/models/c80_map_floors/area.rb +20 -0
  53. data/app/models/c80_map_floors/area_representator.rb +75 -0
  54. data/app/models/c80_map_floors/base_map_object.rb +41 -0
  55. data/app/models/c80_map_floors/building_representator.rb +72 -0
  56. data/app/models/c80_map_floors/floor.rb +37 -0
  57. data/app/models/c80_map_floors/map_building.rb +45 -0
  58. data/app/models/c80_map_floors/map_json.rb +35 -0
  59. data/app/models/c80_map_floors/setting.rb +32 -0
  60. data/app/uploaders/c80_map_floors/building_image_uploader.rb +31 -0
  61. data/app/uploaders/c80_map_floors/floor_image_uploader.rb +33 -0
  62. data/app/uploaders/c80_map_floors/map_image_uploader.rb +31 -0
  63. data/app/views/c80_map_floors/_map_row_index.html.erb +40 -0
  64. data/app/views/c80_map_floors/ajax/fetch_unlinked_areas.js.erb +7 -0
  65. data/app/views/c80_map_floors/ajax/fetch_unlinked_buildings.js.erb +7 -0
  66. data/app/views/c80_map_floors/ajax/map_edit_buttons.js.erb +36 -0
  67. data/app/views/c80_map_floors/ajax/shared/_map_creating.html.erb +6 -0
  68. data/app/views/c80_map_floors/ajax/shared/_map_editing.html.erb +4 -0
  69. data/app/views/c80_map_floors/ajax/shared/_map_removing.html.erb +5 -0
  70. data/app/views/c80_map_floors/ajax/shared/_select_list_unlinked_areas.html.erb +6 -0
  71. data/app/views/c80_map_floors/ajax/shared/_select_list_unlinked_buildings.html.erb +10 -0
  72. data/app/views/c80_map_floors/shared/_modal_window.html.erb +28 -0
  73. data/app/views/c80_map_floors/shared/_save_preloader.html.erb +3 -0
  74. data/app/views/c80_map_floors/shared/map_row/_area_order_button.html.erb +7 -0
  75. data/app/views/c80_map_floors/shared/map_row/_building_info.html.erb +17 -0
  76. data/bin/console +14 -0
  77. data/bin/setup +7 -0
  78. data/c80_map_floors.gemspec +28 -0
  79. data/config/routes.rb +4 -0
  80. data/db/migrate/20161015190000_create_c80_map_floors_settings.rb +8 -0
  81. data/db/migrate/20161015190001_create_c80_map_floors_map_buildings.rb +10 -0
  82. data/db/migrate/20161015190002_create_c80_map_floors_areas.rb +12 -0
  83. data/db/migrate/20161015190003_add_building_representator_to_c80_map_floors_buildings.rb +6 -0
  84. data/db/migrate/20161015190004_create_c80_map_floors_floors.rb +16 -0
  85. data/db/migrate/20161019111010_add_title_to_c80_map_floors_buildings.rb +5 -0
  86. data/db/migrate/20161020184040_add_coords_img_to_c80_map_floors_buildings.rb +5 -0
  87. data/db/seeds/c80_map_floors_01_fill_map_settings.rb +6 -0
  88. data/db/seeds/c80_map_floors_02_create_test_area.rb +7 -0
  89. data/lib/c80_map_floors.rb +8 -0
  90. data/lib/c80_map_floors/engine.rb +23 -0
  91. data/lib/c80_map_floors/version.rb +3 -0
  92. metadata +218 -0
@@ -0,0 +1,65 @@
1
+ module C80MapFloors
2
+ class AjaxController < ApplicationController
3
+
4
+ def map_edit_buttons
5
+ # puts "<AjaxController.map_edit_buttons> #{params}"
6
+ end
7
+
8
+ def fetch_unlinked_areas
9
+ # Rails.logger.debug "<AjaxController.fetch_unlinked_areas> params = #{params}"
10
+
11
+ @unlinked_areas = Rent::Area.unlinked_areas
12
+
13
+ end
14
+
15
+ def fetch_unlinked_buildings
16
+ # Rails.logger.debug "<AjaxController.fetch_unlinked_buildings> params = #{params}"
17
+
18
+ @unlinked_buildings = Rent::Building.unlinked_buildings
19
+
20
+ end
21
+
22
+ # связать Rent::Area и Map::Area
23
+ # в процессе произойдёт обновление json-файла с данными
24
+ def link_area
25
+ Rails.logger.debug "<AjaxController.link_area> params = #{params}"
26
+
27
+ rent_area = Rent::Area.find(params[:rent_area_id])
28
+ map_area = C80Map::Area.find(params[:map_area_id])
29
+ rent_area.map_areas.delete_all
30
+ rent_area.map_areas << map_area
31
+ rent_area.save
32
+
33
+ result = {
34
+ updated_locations_json: C80Map::MapJson.fetch_json
35
+ }
36
+
37
+ respond_to do |format|
38
+ format.json { render json: result }
39
+ end
40
+
41
+ end
42
+
43
+ #
44
+ def link_building
45
+
46
+ Rails.logger.debug "<AjaxController.link_building> params = #{params}"
47
+
48
+ rent_building = Rent::Building.find(params[:rent_building_id])
49
+ map_building = C80Map::MapBuilding.find(params[:map_building_id])
50
+ rent_building.map_buildings.delete_all
51
+ rent_building.map_buildings << map_building
52
+ rent_building.save
53
+
54
+ result = {
55
+ updated_locations_json: C80Map::MapJson.fetch_json
56
+ }
57
+
58
+ respond_to do |format|
59
+ format.json { render json: result }
60
+ end
61
+
62
+ end
63
+
64
+ end
65
+ end
@@ -0,0 +1,6 @@
1
+ module C80MapFloors
2
+ class ApplicationController < ActionController::Base
3
+ protect_from_forgery with: :exception
4
+ before_filter :authenticate_admin_user!
5
+ end
6
+ end
@@ -0,0 +1,70 @@
1
+ module C80MapFloors
2
+ class MapAjaxController < ApplicationController
3
+
4
+ def save_map_data
5
+ # Rails.logger.debug "<MapAjaxController.save_map_data> params = #{params}"
6
+
7
+ #{ "buildings"=>{"0"=>{"coords"=>["2496.5894495412845",...]}} }
8
+ #{ "areas"=>{"0"=>{"coords"=>["2496.5894495412845",...]}} }
9
+
10
+ # ЗДАНИЯ
11
+ # в случае успеха - вернём id созданного здания,
12
+ # тогда js обновит id и перенесёт здание из массива "новые здания" (drawn_buildings).
13
+ # в случае неудачи - вернём описание ошибки
14
+ # завершаем всё обновленным locations.json, который Map возьмёт
15
+ # и положит в data
16
+
17
+ result = {
18
+ areas: [],
19
+ buildings: [],
20
+ updated_locations_json: nil
21
+ }
22
+
23
+ # сначала создадим здания
24
+ if params[:buildings].present?
25
+ params[:buildings].each_key do |key|
26
+ new_building_options = params[:buildings][key]
27
+ # puts "<MapAjaxController.save_map_data> new_building_options = #{new_building_options}"
28
+ # puts "<MapAjaxController.save_map_data> new_building_options[:coords] = #{new_building_options[:coords]}"
29
+ b = C80MapFloors::MapBuilding.new({ coords: new_building_options[:coords].join(',') })
30
+
31
+ if b.valid?
32
+ b.save
33
+ result[:buildings] << { id: b.id, old_temp_id: new_building_options["id"] }
34
+ else
35
+ result[:buildings] << { id: new_building_options.id, status: 'error' }
36
+ end
37
+ end
38
+ end
39
+
40
+ # затем создадим области
41
+ if params[:areas].present?
42
+ params[:areas].each_key do |key|
43
+ new_area_options = params[:areas][key]
44
+ # Rails.logger.debug "<MapAjaxController.save_map_data> new_area_options = #{new_area_options}"
45
+ # puts "<MapAjaxController.save_map_data> new_area_options[:coords] = #{new_area_options[:coords]}"
46
+ a = C80MapFloors::Area.new({
47
+ coords: new_area_options[:coords].join(','),
48
+ map_building_id: new_area_options[:parent_building_id]
49
+ })
50
+
51
+ if a.valid?
52
+ a.save
53
+ result[:areas] << { id: a.id, old_temp_id: new_area_options["id"] }
54
+ else
55
+ result[:areas] << { id: new_area_options.id, status: 'error' }
56
+ end
57
+ end
58
+ end
59
+
60
+ result[:updated_locations_json] = MapJson.fetch_json
61
+
62
+ puts "<MapAjaxController.save_map_data> result = #{result.to_json}"
63
+
64
+ respond_to do |format|
65
+ format.json { render json: result }
66
+ end
67
+ end
68
+
69
+ end
70
+ end
@@ -0,0 +1,28 @@
1
+ module C80MapFloors
2
+ module ApplicationHelper
3
+
4
+ def render_map
5
+
6
+ # map_settings = C80MapFloors::Setting.first
7
+
8
+
9
+ # т.к. в json попадают строки вида
10
+ # /home/scout/git/bitbucket/vorsa/public/uploads/map/map.jpg
11
+ # извлечём эту строку, затем во вью обработаем её image_path
12
+
13
+ p = Rails.root.join("public", "locations.json")
14
+ locs = File.read(p)
15
+ locs_hash = JSON.parse(locs)
16
+ locs_hash["img"] = image_path(locs_hash["img"])
17
+
18
+ render :partial => 'c80_map_floors/map_row_index',
19
+ :locals => {
20
+ locs_hash: locs_hash,
21
+ mapwidth: locs_hash["mapwidth"],
22
+ mapheight: locs_hash["mapheight"]
23
+ }
24
+
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,20 @@
1
+ require 'c80_map_floors/base_map_object'
2
+
3
+ module C80MapFloors
4
+ class Area < ActiveRecord::Base
5
+
6
+ belongs_to :floor
7
+ belongs_to :area_representator, :polymorphic => true
8
+ # validates :coords, uniqueness: true
9
+ acts_as_base_map_object
10
+
11
+ # after_save :update_json
12
+
13
+ # protected
14
+
15
+ # def update_json
16
+ # MapJson.update_json
17
+ # end
18
+
19
+ end
20
+ end
@@ -0,0 +1,75 @@
1
+ module C80MapFloors
2
+
3
+ module AreaRepresentator
4
+
5
+ extend ActiveSupport::Concern
6
+
7
+ # ERROR: Cannot define multiple 'included' blocks for a Concern
8
+ # included do
9
+ #
10
+ # end
11
+
12
+ def self.included(klass)
13
+ klass.extend ClassMethods
14
+ klass.send(:include, InstanceMethods)
15
+ end
16
+
17
+ module ClassMethods
18
+
19
+ def acts_as_map_area_representator
20
+ class_eval do
21
+
22
+ has_many :map_areas, :as => :area_representator, :class_name => 'C80MapFloors::Area', :dependent => :destroy
23
+ after_save :update_json
24
+
25
+ def self.unlinked_areas
26
+ res = []
27
+ self.all.each do |area|
28
+ if area.map_areas.count == 0
29
+ res << area
30
+ end
31
+ end
32
+ res
33
+ end
34
+
35
+ def update_json
36
+ MapJson.update_json
37
+ end
38
+
39
+ end
40
+ end
41
+ end
42
+
43
+ module InstanceMethods
44
+
45
+ def to_hash_a
46
+ res = {
47
+ id: id,
48
+ title: title,
49
+ props: {
50
+ square: square,
51
+ floor_height: floor_height,
52
+ gate_type: gate_type,
53
+ desc: desc,
54
+ column_step: column_step,
55
+ communications: communications,
56
+ price: price_string
57
+ }
58
+ }
59
+ res
60
+ end
61
+
62
+ # свободна ли площадь, привязанная к полигону на карте
63
+ def is_free?
64
+ res = true
65
+ if map_areas.count > 0
66
+ res = map_areas.first.is_free?
67
+ end
68
+ res
69
+ end
70
+ end
71
+
72
+ end
73
+ end
74
+
75
+ ActiveRecord::Base.send :include, C80MapFloors::AreaRepresentator
@@ -0,0 +1,41 @@
1
+ module C80MapFloors
2
+ module BaseMapObject
3
+
4
+ extend ActiveSupport::Concern
5
+
6
+ def self.included(klass)
7
+ klass.extend ClassMethods
8
+ klass.send(:include, InstanceMethods)
9
+ end
10
+
11
+ module ClassMethods
12
+
13
+ def acts_as_base_map_object
14
+ class_eval do
15
+
16
+ # has_many :map_buildings, :as => :building_representator, :class_name => 'C80MapFloors::MapBuilding', :dependent => :destroy
17
+ after_save :update_json
18
+ # after_destroy :update_json
19
+ validates :coords, uniqueness: true
20
+
21
+ def update_json
22
+ MapJson.update_json
23
+ end
24
+
25
+ end
26
+ end
27
+ end
28
+
29
+ module InstanceMethods
30
+
31
+ # используется для сопоставления js классов
32
+ def class_name
33
+ self.class.name
34
+ end
35
+
36
+ end
37
+
38
+ end
39
+ end
40
+
41
+ ActiveRecord::Base.send :include, C80MapFloors::BaseMapObject
@@ -0,0 +1,72 @@
1
+ module C80MapFloors
2
+
3
+ module BuildingRepresentator
4
+
5
+ extend ActiveSupport::Concern
6
+
7
+ # ERROR: Cannot define multiple 'included' blocks for a Concern
8
+ # included do
9
+ #
10
+ # end
11
+
12
+ def self.included(klass)
13
+ klass.extend ClassMethods
14
+ klass.send(:include, InstanceMethods)
15
+ end
16
+
17
+ module ClassMethods
18
+
19
+ def acts_as_map_building_representator
20
+ class_eval do
21
+
22
+ has_many :map_buildings, :as => :building_representator, :class_name => 'C80MapFloors::MapBuilding', :dependent => :destroy
23
+ after_save :update_json
24
+
25
+ def self.unlinked_buildings
26
+ res = []
27
+ self.all.each do |building|
28
+ # if building.map_buildings.count == 0
29
+ res << building
30
+ # end
31
+ end
32
+ res
33
+ end
34
+
35
+ def update_json
36
+ MapJson.update_json
37
+ end
38
+
39
+ end
40
+ end
41
+ end
42
+
43
+ module InstanceMethods
44
+
45
+ def to_hash
46
+
47
+ Rails.logger.debug "<BuildingRepresentator.to_hash> self.free_square = #{self.free_square}"
48
+
49
+ res = {
50
+ id: self.id,
51
+ title: self.title,
52
+ props: {
53
+ square: self.square,
54
+ free_square: self.free_square,
55
+ floor_height: self.floor_height,
56
+ gate_type: self.gate_type,
57
+ desc: self.desc,
58
+ column_step: self.column_step,
59
+ communications: self.communications,
60
+ price: self.price_string,
61
+ free_areas_count: self.free_areas_count # NOTE: free_areas_count находися в Rent::Building проекта vorsa
62
+ }
63
+ }
64
+ res
65
+ end
66
+
67
+ end
68
+
69
+ end
70
+ end
71
+
72
+ ActiveRecord::Base.send :include, C80MapFloors::BuildingRepresentator
@@ -0,0 +1,37 @@
1
+ require 'c80_map_floors/base_map_object'
2
+
3
+ module C80MapFloors
4
+ class Floor < ActiveRecord::Base
5
+
6
+ belongs_to :map_building
7
+ has_many :areas, :class_name => 'C80MapFloors::Area', :dependent => :destroy
8
+ acts_as_base_map_object
9
+
10
+ # validates :coords, uniqueness: true
11
+ # after_save :update_json
12
+
13
+ mount_uploader :img_bg, C80MapFloors::FloorImageUploader # TODO:: FloorImageUploader класс должен использоваться только для загрузки img_bg [потому что 78aasq]
14
+ mount_uploader :img_overlay, C80MapFloors::FloorImageUploader
15
+
16
+ # NOTE:: Т.к. для этажей используются картинки в два раза детальнее (в два раза больше, чем оригинал карты), то делим попалам
17
+ # размеры картинки уйдут в js - они помогут её css-абсолютно правильно масштабировать и позиционировать
18
+ def img_bg_width
19
+ img = MiniMagick::Image.open(img_bg.path)
20
+ img["width"]/2
21
+ end
22
+
23
+ def img_bg_height
24
+ img = MiniMagick::Image.open(img_bg.path)
25
+ img["height"]/2
26
+ end
27
+
28
+ # private
29
+
30
+ # TODO:: после того, как апдейтим этаж, не обновляются данные в JSON - изза ебучей ошибки с путями в CarrierWave
31
+ def update_json
32
+ Rails.logger.debug "[TRACE] <update_json> nope"
33
+ # MapJson.update_json
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,45 @@
1
+ require 'c80_map_floors/base_map_object'
2
+
3
+ module C80MapFloors
4
+ class MapBuilding < ActiveRecord::Base
5
+
6
+ has_many :floors, :class_name => 'C80MapFloors::Floor', :dependent => :destroy
7
+ belongs_to :building_representator, :polymorphic => true
8
+ # validates :coords, uniqueness: true
9
+ # after_save :update_json
10
+ acts_as_base_map_object
11
+
12
+ mount_uploader :img, C80MapFloors::BuildingImageUploader
13
+
14
+ def areas
15
+ C80MapFloors::Areas.joins(:c80_map_floors_floors).where(:building_id => self.if)
16
+ end
17
+
18
+ def as_json(options = nil)
19
+
20
+ super({
21
+ :except => [:created_at,:updated_at,:building_representator_type],
22
+ :methods => :class_name,
23
+ :include => [
24
+ :floors => {
25
+ :except => [:created_at,:updated_at],
26
+ :methods => [:class_name, :img_bg_width, :img_bg_height],
27
+ :include => [
28
+ :areas => {
29
+ :except => [:created_at,:updated_at,:area_representator_type],
30
+ :methods => :class_name
31
+ }
32
+ ]
33
+ }
34
+ ]
35
+ }.merge(options || {} ))
36
+ end
37
+
38
+ # private
39
+
40
+ # def update_json
41
+ # MapJson.update_json
42
+ # end
43
+
44
+ end
45
+ end