c80_map_floors 0.1.0.5 → 0.1.0.6
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 +4 -4
- data/app/assets/javascripts/buttons/admin_buttons/button_floor_link.js +122 -0
- data/app/assets/javascripts/c80_map_floors.js.coffee +1 -1
- data/app/assets/javascripts/map_objects/area.js +34 -11
- data/app/assets/javascripts/map_objects/building.js +59 -15
- data/app/assets/javascripts/src/main.js +58 -31
- data/app/assets/javascripts/src/state_controller.js +8 -4
- data/app/assets/stylesheets/map.scss +3 -3
- data/app/assets/stylesheets/view/modal_window.scss +5 -0
- data/app/controllers/c80_map_floors/ajax_controller.rb +9 -0
- data/app/controllers/c80_map_floors/map_ajax_controller.rb +14 -3
- data/app/models/c80_map_floors/floor_representator.rb +3 -1
- data/app/views/c80_map_floors/ajax/fetch_unlinked_floors.js.erb +7 -0
- data/app/views/c80_map_floors/ajax/map_edit_buttons.js.erb +3 -0
- data/app/views/c80_map_floors/ajax/shared/_select_list_unlinked_floors.html.erb +6 -0
- data/app/views/c80_map_floors/shared/_modal_window.html.erb +1 -1
- data/config/routes.rb +2 -0
- data/lib/c80_map_floors/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 665f2daf916815f816c9855be418fc89254b833d
|
4
|
+
data.tar.gz: c7130c9f88fef43e6c995203e407c03db2fd1156
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2819689d023aacb12978e264e04d6404c78d043b8bd13d9230a536df7639d66eb1381a42510e2f6495e2fc87d4b0b17110e4429ea5422b3a193dbf2f82092a35
|
7
|
+
data.tar.gz: bfa6ac82494fa655b1d7e27b2d0f5e388b70d5ce0fbdd685d5495db03f8134b594ccc78acbaa97f102e2339d60080058aab38a1fbbbf9d38f98d98276bc3b472
|
@@ -0,0 +1,122 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
// при клике на эту кнопку произойдет:
|
4
|
+
// * показ прелоадера,
|
5
|
+
// * запрос за несвязанными этажами здания,
|
6
|
+
// * после получения ответа - показ модального окна _modal_window.html.erb куда будет подставлен %modal-title% и %modal-body%
|
7
|
+
|
8
|
+
function FloorLinkButton() {
|
9
|
+
|
10
|
+
var _map = null;
|
11
|
+
var _this = this;
|
12
|
+
_this.el = null;
|
13
|
+
|
14
|
+
// служебная невидимая ссылка, js-клик по которой покажет модальное окно
|
15
|
+
var $link_show_modal_window = null;
|
16
|
+
|
17
|
+
// настроить и показать модальное окно
|
18
|
+
var show_modal_window = function () {
|
19
|
+
|
20
|
+
//var $dialog = $('#modal_window');
|
21
|
+
//$dialog.find("h4").text($t.data("wtitle"));
|
22
|
+
//$dialog.find("#form_comment").css('display','block');
|
23
|
+
//$dialog.find("input#comment_part_id").val(partid);
|
24
|
+
//$dialog.find("input#comment_author").val(author);
|
25
|
+
|
26
|
+
// фиксируем участников
|
27
|
+
var $m = $('#modal_window');
|
28
|
+
var $cc = $m.find('.modal-body');
|
29
|
+
|
30
|
+
// устанавливаем заголовок окна
|
31
|
+
$m.find('.modal-title').text('Укажите Этаж, соответствующий этой картинке.');
|
32
|
+
|
33
|
+
// инициализируем bootstrap-selectpicker
|
34
|
+
setTimeout(function () {
|
35
|
+
$("select#unlinked_floors").selectpicker({size: 50, tickIcon: 'hidden'});
|
36
|
+
}, 10);
|
37
|
+
|
38
|
+
// клик по кнопке "применить" вызовет _map.link_floor()
|
39
|
+
setTimeout(function () {
|
40
|
+
//console.log($cc.find("button"));
|
41
|
+
$cc.find("button").on('click', function () {
|
42
|
+
if ($(this).attr('id') == "submit_floor_link") {
|
43
|
+
_map.link_floor();
|
44
|
+
}
|
45
|
+
});
|
46
|
+
}, 1000);
|
47
|
+
|
48
|
+
// нажмём служебную ссылку, которая откроет модальное окно
|
49
|
+
$link_show_modal_window.click();
|
50
|
+
|
51
|
+
};
|
52
|
+
|
53
|
+
/** функция, запрашивающая с сервера Этажи без полигонов (указанного Здания).
|
54
|
+
*
|
55
|
+
* @param bid - ID Здания, которому должны принадлежать Этажи без полигонов
|
56
|
+
*/
|
57
|
+
var fetch_free_floors = function (bid) {
|
58
|
+
console.log('<ButtonFloorLink.fetch_free_floors> Запросим Этажи без полигонов для bid:' + bid);
|
59
|
+
|
60
|
+
$.ajax({
|
61
|
+
url:'/ajax/fetch_unlinked_floors',
|
62
|
+
type:'POST',
|
63
|
+
data: {
|
64
|
+
building_id:bid
|
65
|
+
},
|
66
|
+
dataType:'script'
|
67
|
+
}).done(fetch_free_floors_done);
|
68
|
+
};
|
69
|
+
|
70
|
+
// при успешном ответе - скроем прелоадер, покажем модальное окно
|
71
|
+
//noinspection JSUnusedLocalSymbols
|
72
|
+
var fetch_free_floors_done = function (data, result) {
|
73
|
+
_map.save_preloader_klass.hide();
|
74
|
+
show_modal_window();
|
75
|
+
};
|
76
|
+
|
77
|
+
// при клике по кнопке "назначить Этаж" - покажем прелоадер, запросим данные с сервера
|
78
|
+
this.onClick = function (e) {
|
79
|
+
if (_this.el.hasClass('disabled')) return;
|
80
|
+
e.preventDefault();
|
81
|
+
|
82
|
+
//console.log("<FloorLinkButton.click>");
|
83
|
+
|
84
|
+
// ID Здания, которому должны принадлежать Этажи без полигонов
|
85
|
+
var bid = _map.current_building.get_bid();
|
86
|
+
|
87
|
+
if (bid == undefined || bid == null) {
|
88
|
+
alert('[ERROR] Перед тем, как назначать Этаж, необходимо назначить Здание полигону.');
|
89
|
+
} else {
|
90
|
+
_map.save_preloader_klass.show();
|
91
|
+
fetch_free_floors(bid);
|
92
|
+
}
|
93
|
+
};
|
94
|
+
|
95
|
+
// инициализация
|
96
|
+
this.init = function (button_css_selector, link_to_map) {
|
97
|
+
|
98
|
+
// фиксируем элементы, настраиваем
|
99
|
+
_map = link_to_map;
|
100
|
+
_this.el = $(button_css_selector);
|
101
|
+
_this.el.on('click', _this.onClick);
|
102
|
+
|
103
|
+
// изначально кнопка "назначить Этаж" скрыта
|
104
|
+
_this.hide();
|
105
|
+
|
106
|
+
// найдем ссылку, клик по которой покажет окно [_modal_window.html.erb]
|
107
|
+
$link_show_modal_window = $('.show_modal_window');
|
108
|
+
|
109
|
+
};
|
110
|
+
|
111
|
+
// спрятать кнопку "назначить этаж"
|
112
|
+
this.hide = function () {
|
113
|
+
_this.el.css('display','none');
|
114
|
+
};
|
115
|
+
|
116
|
+
// показать кнопку "назначить этаж"
|
117
|
+
this.show = function () {
|
118
|
+
//console.log("<FloorLinkButton.show>");
|
119
|
+
_this.el.css('display','block');
|
120
|
+
};
|
121
|
+
|
122
|
+
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
#= require history_jquery
|
2
2
|
#= require bootstrap/transition
|
3
|
-
|
3
|
+
# require bootstrap/modal # Bootstrap Modal immediately disappearing: http://stackoverflow.com/a/13670437 # т.к. 101км это первый проект и там уже много нахуеверчено, в том числе: bootstrap.min.js лежит в папке lib/, то эту строку комментируем (только для 101km)
|
4
4
|
#= require bootstrap/tooltip
|
5
5
|
#= require bootstrap/alert
|
6
6
|
#= require bootstrap/dropdown
|
@@ -25,12 +25,37 @@ function Area() {
|
|
25
25
|
// нарисован и ждёт сохранения на сервере
|
26
26
|
//_this.is_new = false;
|
27
27
|
|
28
|
-
_this.init = function (options,
|
29
|
-
|
30
|
-
|
28
|
+
_this.init = function (options, parent_floor_json, pself) {
|
29
|
+
|
30
|
+
console.log("<Area.init> options: ");
|
31
|
+
console.log(options);
|
32
|
+
|
33
|
+
// нарисовали полигон площади, находясь на этаже:
|
34
|
+
// => Object { coords: Array[8] }
|
35
|
+
|
36
|
+
// полигон площади уже был нарисован, просто вошли на этаж:
|
37
|
+
// => Object { id: 2, tag: "test_area", floor_id: 2, class_name: "C80MapFloors::Area", coords: "10,12,110,112", data: null }
|
38
|
+
|
39
|
+
console.log("<Area.init> parent_floor_json: ");
|
40
|
+
console.log(parent_floor_json);
|
41
|
+
|
42
|
+
/*
|
43
|
+
Object {
|
44
|
+
ord: 1,
|
45
|
+
id: 2,
|
46
|
+
title: "Первый этаж",
|
47
|
+
tag: "21.1",
|
48
|
+
class_name: "C80MapFloors::Floor",
|
49
|
+
map_building_id: 7,
|
50
|
+
img_bg: Object,
|
51
|
+
img_overlay: Object,
|
52
|
+
img_bg_width: 387,
|
53
|
+
img_bg_height: 225,
|
54
|
+
3 more…
|
55
|
+
}
|
56
|
+
*/
|
31
57
|
|
32
|
-
//
|
33
|
-
/*{
|
58
|
+
/*{ // так было в c80_map
|
34
59
|
"id": 1,
|
35
60
|
"object_type": "area",
|
36
61
|
"area_hash": {
|
@@ -67,13 +92,11 @@ function Area() {
|
|
67
92
|
_this._options.coords[i] = Number(_this._options.coords[i]);
|
68
93
|
}
|
69
94
|
|
70
|
-
_this._options
|
71
|
-
//console.log(_this._options.parent_building_hash);
|
72
|
-
|
95
|
+
_this._options["parent_floor_json"] = parent_floor_json;
|
73
96
|
|
74
97
|
_this._polygon = Polygon.createFromSaved(options, false, _map);
|
75
98
|
_this._polygon.area = _this;
|
76
|
-
_this._polygon
|
99
|
+
_this._polygon["parent_floor_json"] = parent_floor_json;
|
77
100
|
_this._polygon = $(_this._polygon.polygon);
|
78
101
|
|
79
102
|
// подпись над полигоном показываем только админам
|
@@ -102,7 +125,7 @@ function Area() {
|
|
102
125
|
|
103
126
|
// optimisation
|
104
127
|
var timeoutEnter = function () {
|
105
|
-
_map.showAreaInfo(_this._options
|
128
|
+
_map.showAreaInfo(_this._options["data"], _this._options["parent_floor_json"]);
|
106
129
|
_map.setMode('view_area');
|
107
130
|
};
|
108
131
|
|
@@ -245,7 +268,7 @@ function Area() {
|
|
245
268
|
return {
|
246
269
|
id: _this._options["id"],
|
247
270
|
coords: _this._options["coords"],
|
248
|
-
|
271
|
+
parent_floor_id: _this._options["parent_floor_json"]["id"]
|
249
272
|
}
|
250
273
|
}
|
251
274
|
}
|
@@ -24,6 +24,9 @@ function Building() {
|
|
24
24
|
var _$image_bg = null;
|
25
25
|
var _image_overlay = null;
|
26
26
|
|
27
|
+
// если вошли в какой-то этаж - эта переменная будет хранить ссылку на объект с данными полигона Этажа из locations.json
|
28
|
+
var _json_current_floor = null;
|
29
|
+
|
27
30
|
var _zoomToMe = function () {
|
28
31
|
|
29
32
|
/* рассчитаем масштаб, при котором можно вписать прямоугольник дома в прямоугольник рабочей области */
|
@@ -49,7 +52,7 @@ function Building() {
|
|
49
52
|
_map.moveTo(x, y, scale, 400, 'easeInOutCubic');
|
50
53
|
};
|
51
54
|
|
52
|
-
//
|
55
|
+
// map_floor_as_json - это as_json модели C80MapFloors::Floor
|
53
56
|
/*{
|
54
57
|
"map_building_id": 7,
|
55
58
|
"img_bg": {
|
@@ -74,17 +77,27 @@ function Building() {
|
|
74
77
|
"coords": "10,12,110,112",
|
75
78
|
"area_representator_id": null,
|
76
79
|
"class_name": "C80MapFloors::Area"
|
80
|
+
},
|
81
|
+
"data": {
|
82
|
+
"id": 1,
|
83
|
+
"title": "test building",
|
84
|
+
"square": null,
|
85
|
+
"square_free": null,
|
86
|
+
"desc": null,
|
87
|
+
"floor_height": "2.3м - 4.2м",
|
88
|
+
"price_string": "От 300 руб/м.кв.",
|
89
|
+
"communications": "Интернет, Вода, Свет"
|
77
90
|
}
|
78
91
|
]
|
79
92
|
}*/
|
80
|
-
var _draw_floor = function (
|
93
|
+
var _draw_floor = function (map_floor_as_json) {
|
81
94
|
//console.log('<Building._draw_floor>');
|
82
95
|
|
83
96
|
// это тот самый код, который остался без изменений с версии c80_map (прошлой версии)
|
84
|
-
if (
|
85
|
-
//_image_overlay = _map.draw_child_bg_image(
|
97
|
+
if (map_floor_as_json["img_overlay"]["url"] != "null") {
|
98
|
+
//_image_overlay = _map.draw_child_bg_image(map_floor_as_json["img_overlay"]["url"], 'building', true);
|
86
99
|
}
|
87
|
-
if (
|
100
|
+
if (map_floor_as_json["img_bg"]["url"] != "null") {
|
88
101
|
|
89
102
|
// NOTE::картинку этажа рисуем не по bounding box здания, а по значениям из базы
|
90
103
|
|
@@ -96,8 +109,8 @@ function Building() {
|
|
96
109
|
// и сложим их с корректирующими координатами coords этажа
|
97
110
|
var xx2 = 0;
|
98
111
|
var yy2 = 0;
|
99
|
-
if (
|
100
|
-
var tmp2 =
|
112
|
+
if (map_floor_as_json["coords"].length) {
|
113
|
+
var tmp2 = map_floor_as_json["coords"].split(',');
|
101
114
|
xx2 = parseInt(tmp2[0]);
|
102
115
|
yy2 = parseInt(tmp2[1]);
|
103
116
|
}
|
@@ -106,19 +119,19 @@ function Building() {
|
|
106
119
|
_map.mark_all_map_object_images_for_clean();
|
107
120
|
|
108
121
|
// просим карту нарисовать картинку с данными характеристиками
|
109
|
-
_$image_bg = _map.draw_map_object_image_bg(
|
122
|
+
_$image_bg = _map.draw_map_object_image_bg(map_floor_as_json["img_bg"]["url"], {
|
110
123
|
x: xx + xx2,
|
111
124
|
y: yy + yy2,
|
112
|
-
width:
|
113
|
-
height:
|
125
|
+
width: map_floor_as_json["img_bg_width"],
|
126
|
+
height: map_floor_as_json["img_bg_height"]
|
114
127
|
}/*, 'building'*/);
|
115
128
|
|
116
129
|
} else {
|
117
130
|
alert('[ERROR] У этажа нет картинки.');
|
118
131
|
}
|
119
132
|
|
120
|
-
// просим карту нарисовать
|
121
|
-
_map.draw_childs(
|
133
|
+
// просим карту нарисовать полигоны площадей
|
134
|
+
_map.draw_childs(map_floor_as_json["areas"], map_floor_as_json);
|
122
135
|
|
123
136
|
};
|
124
137
|
|
@@ -156,6 +169,8 @@ function Building() {
|
|
156
169
|
if (typeof _this.options["coords"] == 'string') { /* когда нажимаем ENTER в редакторе и завершаем рисование полигона - приходит массив */
|
157
170
|
_this.options["coords"] = _this.options["coords"].split(',');
|
158
171
|
}
|
172
|
+
|
173
|
+
//#-> [iddqd] ВАЖНО: это id полигона здания
|
159
174
|
_this.id = options["id"];
|
160
175
|
|
161
176
|
// [NOTE::56dfaw1: парсим координаты объекта на карте, поданные в виде строки]
|
@@ -164,6 +179,7 @@ function Building() {
|
|
164
179
|
}
|
165
180
|
|
166
181
|
// [4ddl5df]: в случае, если это только что отрисованное Здание - генерим временный случайный id
|
182
|
+
//#-> [iddqd] А как же тогда _this.id ? Он будет undefined? Страшно ли это?
|
167
183
|
if (_this.options["id"] == undefined) {
|
168
184
|
_this.options["id"] = Math.ceil((Math.random()*100000));
|
169
185
|
}
|
@@ -230,11 +246,18 @@ function Building() {
|
|
230
246
|
* @param floor_id
|
231
247
|
*/
|
232
248
|
_this.enterFloor = function (floor_id) {
|
233
|
-
|
249
|
+
|
250
|
+
// при входе в этаж - удаляем все кликабельные полигоны с карты
|
251
|
+
_map.svgRemoveAllNodes();
|
234
252
|
|
235
253
|
var flr = _map_floors_hash[floor_id];
|
236
254
|
if (flr != undefined) {
|
255
|
+
// рисуем картинку этажа (там же будет заказ на отрисовку полигонов площадей)
|
237
256
|
_draw_floor(flr);
|
257
|
+
// фиксируем текущий этаж
|
258
|
+
_json_current_floor = flr;
|
259
|
+
console.log('<Building.enterFloor> Вошли на этаж floor_id: ' + floor_id + "; данные полигона этажа: ");
|
260
|
+
console.log(_json_current_floor);
|
238
261
|
} else {
|
239
262
|
alert('[Building.EnterFloor] error: Нет данных об этаже [карты] floor_id='+floor_id+'.');
|
240
263
|
}
|
@@ -250,6 +273,15 @@ function Building() {
|
|
250
273
|
_$image_bg = null;
|
251
274
|
_image_overlay = null;
|
252
275
|
//_zoomToMe();
|
276
|
+
|
277
|
+
// чистим переменную "текущий этаж"
|
278
|
+
_json_current_floor = null;
|
279
|
+
|
280
|
+
};
|
281
|
+
|
282
|
+
// выдать данные текущего полигона этажа
|
283
|
+
_this.json_current_floor = function () {
|
284
|
+
return _json_current_floor;
|
253
285
|
};
|
254
286
|
|
255
287
|
// выдать центр дома в логических координатах
|
@@ -317,8 +349,20 @@ function Building() {
|
|
317
349
|
|
318
350
|
_this.to_json = function () {
|
319
351
|
return {
|
320
|
-
id: _this.options["id"],
|
352
|
+
id: _this.options["id"], //#-> [iddqd] А здесь не используется _this.id (т.е. в случае, когда полигон был только что нарисован, to_json вернёт актуальное, правильное значение
|
321
353
|
coords: _this.options["coords"]
|
322
354
|
}
|
323
|
-
}
|
355
|
+
};
|
356
|
+
|
357
|
+
// выдать id привязанного к полигону Здания
|
358
|
+
this.get_bid = function () {
|
359
|
+
var result = null;
|
360
|
+
if (_options != null) {
|
361
|
+
if (_options["data"] != null && _options["data"] != undefined) {
|
362
|
+
result = _options["data"]["id"];
|
363
|
+
}
|
364
|
+
}
|
365
|
+
return result;
|
366
|
+
};
|
367
|
+
|
324
368
|
}
|
@@ -81,6 +81,8 @@ var InitMap = function (params) {
|
|
81
81
|
self.is_draw = false;
|
82
82
|
self.save_button_klass = null;
|
83
83
|
self.area_link_button_klass = null;
|
84
|
+
self.building_link_button_klass = null;
|
85
|
+
self.floor_link_button_klass = null;
|
84
86
|
self.drawn_areas = []; // если имеются нарисованные но несохранённые Площади - они хранятся тут
|
85
87
|
self.drawn_buildings = []; // если имеются нарисованные но несохранённые Здания - они хранятся тут
|
86
88
|
self.save_preloader_klass = null;
|
@@ -261,6 +263,10 @@ var InitMap = function (params) {
|
|
261
263
|
self.area_link_button_klass = new AreaLinkButton();
|
262
264
|
self.area_link_button_klass.init('.mapplic-area-link-button', self);
|
263
265
|
|
266
|
+
// при клике на эту кнопку произойдет показ модального окна "связать полигон этажа с Этажом"
|
267
|
+
self.floor_link_button_klass = new FloorLinkButton();
|
268
|
+
self.floor_link_button_klass.init('.mapplic-floor-link-button', self);
|
269
|
+
|
264
270
|
// при клике на эту кнопку произойдет показ модального окна, в котором можно будет указать здание, соответствующее полигону
|
265
271
|
self.building_link_button_klass = new BuildingLinkButton();
|
266
272
|
self.building_link_button_klass.init('.mapplic-building-link-button', self);
|
@@ -281,7 +287,7 @@ var InitMap = function (params) {
|
|
281
287
|
// инициализиуем класс, занимающийся отображением данных о здании\этаже\площади
|
282
288
|
self.building_info_klass = new BuildingInfo({
|
283
289
|
onFloorTabChange: function (floor_id) {
|
284
|
-
self.current_building.enterFloor(floor_id);
|
290
|
+
self.current_building.enterFloor(floor_id); //#-> только с помощью клика по табам можно войти на Этаж
|
285
291
|
}
|
286
292
|
});
|
287
293
|
|
@@ -388,7 +394,8 @@ var InitMap = function (params) {
|
|
388
394
|
|
389
395
|
function onSvgMousedown(e) {
|
390
396
|
|
391
|
-
|
397
|
+
//#-> Убрал 'edit_building', т.к. мы не можем ничего нарисовать в этом режиме - картинки этажей добавляются через админку
|
398
|
+
if (self.mode === 'editing' || self.mode === 'edit_area' || self.mode === 'edit_floor') { // || self.mode === "edit_building"
|
392
399
|
if (e.target.parentNode.tagName === 'g') {
|
393
400
|
console.log("<onSvgMousedown> e = ");
|
394
401
|
//console.log(e.pageX);
|
@@ -579,9 +586,9 @@ var InitMap = function (params) {
|
|
579
586
|
}
|
580
587
|
}
|
581
588
|
|
582
|
-
/* если находимся в режиме просмотра здания - входим в площадь */
|
589
|
+
/* если находимся в режиме просмотра здания - входим в площадь (так было в c80_map) */
|
583
590
|
/* если находится в режиме просмотра площади - переключаемся на другую площадь */
|
584
|
-
else if (self.mode == '
|
591
|
+
else if (self.mode == 'view_floor' || self.mode == 'view_area') { // self.mode == 'view_building' (так было в c80_map)
|
585
592
|
|
586
593
|
//console.log($(event.target).parent());
|
587
594
|
// => g, который живёт в #svg_overlay, или, другими словами,
|
@@ -602,6 +609,8 @@ var InitMap = function (params) {
|
|
602
609
|
console.log("<mouseup> Входим в площадь. self.last_clicked_g = ");
|
603
610
|
console.log(self.last_clicked_g);
|
604
611
|
area.enter();
|
612
|
+
} else {
|
613
|
+
console.log('<mouseup> [ERROR] у полигона нет объекта Area.js класса.');
|
605
614
|
}
|
606
615
|
|
607
616
|
}
|
@@ -702,7 +711,7 @@ var InitMap = function (params) {
|
|
702
711
|
var style = "display:block;position:absolute;background-color:#00ff00;opacity:0.4;";
|
703
712
|
var style_x = style + "width:1px;height:800px;top:0;left:{X}px;";
|
704
713
|
var style_y = style + "width:3000px;height:1px;left:0;top:{Y}px;";
|
705
|
-
var style_dot = style + 'width:4px;height:4px;left:{X}px;top:{Y}px;';
|
714
|
+
//var style_dot = style + 'width:4px;height:4px;left:{X}px;top:{Y}px;';
|
706
715
|
|
707
716
|
var to_draw = [
|
708
717
|
{x: self.X10},
|
@@ -710,11 +719,11 @@ var InitMap = function (params) {
|
|
710
719
|
{y: self.Y10},
|
711
720
|
{y: self.Y20},
|
712
721
|
{x: self.CX},
|
713
|
-
{y: self.CY}
|
722
|
+
{y: self.CY}
|
714
723
|
];
|
715
724
|
|
716
725
|
|
717
|
-
var i, istyle,
|
726
|
+
var i, istyle, ip;
|
718
727
|
for (i = 0; i < to_draw.length; i++) {
|
719
728
|
ip = to_draw[i];
|
720
729
|
|
@@ -787,7 +796,7 @@ var InitMap = function (params) {
|
|
787
796
|
* можно было отобразить характеристики Здания родителя C80Rent:Building.
|
788
797
|
*/
|
789
798
|
self.draw_childs = function (childs, parent_hash) {
|
790
|
-
|
799
|
+
console.log("<Map.draw_childs>");
|
791
800
|
|
792
801
|
//var ip;
|
793
802
|
var iobj;
|
@@ -941,7 +950,7 @@ var InitMap = function (params) {
|
|
941
950
|
};
|
942
951
|
|
943
952
|
self.onDrawStop = function (e) {
|
944
|
-
console.log("<Map.onDrawStop>");
|
953
|
+
console.log("<Map.onDrawStop> Закончили рисовать.");
|
945
954
|
|
946
955
|
if (e != undefined) {
|
947
956
|
if (e.type == 'keydown' && e.keyCode == 13) {
|
@@ -959,22 +968,31 @@ var InitMap = function (params) {
|
|
959
968
|
_n_f.setCoords(_n_f.params).deselect();
|
960
969
|
delete(_n_f.polyline);
|
961
970
|
|
962
|
-
|
963
|
-
|
971
|
+
//#-> создадим либо полигон Здания, либо полигон Площади
|
972
|
+
|
973
|
+
if (self.prev_mode == "edit_floor") {
|
974
|
+
console.log("<Map.onDrawStop> Создаём Area.");
|
975
|
+
|
964
976
|
var bo = self.current_building.options;
|
977
|
+
var fo = self.current_building.json_current_floor();
|
965
978
|
var a = new Area();
|
966
|
-
a.init({ coords:_n_f.params },
|
979
|
+
a.init({ coords:_n_f.params }, fo, self);
|
967
980
|
//a.is_new = true;
|
968
981
|
_n_f.remove(); // удаляем нарисованный полигон, т.к. его уже заменили полигоном Area
|
969
982
|
self.registerJustDrownArea(a);
|
970
983
|
}
|
971
984
|
else if (self.prev_mode == 'editing') {
|
985
|
+
console.log("<Map.onDrawStop> Создаём Building.");
|
972
986
|
var b = new Building();
|
973
987
|
b.init({ coords:_n_f.params }, self);
|
974
988
|
//b.is_new = true;
|
975
989
|
_n_f.remove(); // удаляем нарисованный полигон, т.к. его уже заменили полигоном Building
|
976
990
|
self.registerJustDrownBuilding(b);
|
977
991
|
}
|
992
|
+
//else if (self.prev_mode == 'edit_building') {
|
993
|
+
// todo: new Floor (?)
|
994
|
+
//#-> нет, мы не можем нарисовать полигонЭтажа. Этаж - это картинка, которая просто видна при входе в Этаж, создаётся через админку
|
995
|
+
//}
|
978
996
|
|
979
997
|
self.removeAllEvents();
|
980
998
|
self.drawing_poligon = null;
|
@@ -1006,8 +1024,7 @@ var InitMap = function (params) {
|
|
1006
1024
|
* Зная ширину контейнера и контента,
|
1007
1025
|
* используя указанные параметры,
|
1008
1026
|
* рассчитать нормальный X
|
1009
|
-
* @param
|
1010
|
-
* @param scale
|
1027
|
+
* @param params
|
1011
1028
|
* @returns {*}
|
1012
1029
|
*/
|
1013
1030
|
self.normalizeX = function (params) {
|
@@ -1030,8 +1047,7 @@ var InitMap = function (params) {
|
|
1030
1047
|
* Зная высоту контейнера и контента,
|
1031
1048
|
* используя указанные параметры,
|
1032
1049
|
* рассчитать нормальный Y
|
1033
|
-
* @param
|
1034
|
-
* @param scale
|
1050
|
+
* @param params
|
1035
1051
|
* @returns {*}
|
1036
1052
|
*/
|
1037
1053
|
self.normalizeY = function (params) {
|
@@ -1086,7 +1102,7 @@ var InitMap = function (params) {
|
|
1086
1102
|
* - по регулярке извлекать left и top
|
1087
1103
|
* - трансформировать эти значения
|
1088
1104
|
* - изменить атрибут viewBox обоих svg слоёв
|
1089
|
-
*
|
1105
|
+
*
|
1090
1106
|
* Изначально была задумка каждый шаг анимации вызывать эту функцию.
|
1091
1107
|
* Но затем во время оптимизации слои с svg стали видны только тогда,
|
1092
1108
|
* когда анимация не проходит. По-этому этот код был поставлен на setTimeout
|
@@ -1143,7 +1159,7 @@ var InitMap = function (params) {
|
|
1143
1159
|
__afterMovingCorrectSvgLayersPositions();
|
1144
1160
|
|
1145
1161
|
};
|
1146
|
-
|
1162
|
+
|
1147
1163
|
var __moveToTimeout = function () {
|
1148
1164
|
if (self.mode === 'edit_area'|| self.mode === 'view_area') {
|
1149
1165
|
$("#masked").removeClass('hiddn');
|
@@ -1290,9 +1306,10 @@ var InitMap = function (params) {
|
|
1290
1306
|
};
|
1291
1307
|
|
1292
1308
|
// показать инфо о просматриваемой площади
|
1293
|
-
self.showAreaInfo = function (
|
1309
|
+
self.showAreaInfo = function (area_json, parent_floor_json) {
|
1294
1310
|
//console.log(area_hash);
|
1295
1311
|
|
1312
|
+
// так было в c80_map
|
1296
1313
|
//"area_hash": {
|
1297
1314
|
// "id": 2,
|
1298
1315
|
// "title": "Площадь 2.12",
|
@@ -1306,6 +1323,7 @@ var InitMap = function (params) {
|
|
1306
1323
|
// "price": "от 155 руб/кв.м в месяц"
|
1307
1324
|
// }
|
1308
1325
|
|
1326
|
+
// так было в c80_map
|
1309
1327
|
//"rent_building_hash": {
|
1310
1328
|
// "id": 2,
|
1311
1329
|
// "title": "Здание 2",
|
@@ -1319,20 +1337,24 @@ var InitMap = function (params) {
|
|
1319
1337
|
// "price": "от 155 руб/кв.м в месяц"
|
1320
1338
|
// }
|
1321
1339
|
|
1322
|
-
|
1340
|
+
if (area_json == null || area_json == undefined) {
|
1341
|
+
alert('[ERROR] У полигона нет привязки к Площади. Привяжите полигон площади.');
|
1342
|
+
} else {
|
1343
|
+
$building_info.find("h2").html("</span>" + area_json["title"] + "<span style='color:#D0B2B2;'> / " + parent_floor_json["title"]);
|
1323
1344
|
|
1324
|
-
|
1325
|
-
|
1326
|
-
|
1327
|
-
|
1328
|
-
|
1345
|
+
var v;
|
1346
|
+
for (var p in area_json["props"]) {
|
1347
|
+
v = area_json["props"][p];
|
1348
|
+
$building_info.find("#" + p).find('span').text(v);
|
1349
|
+
}
|
1329
1350
|
|
1330
|
-
|
1351
|
+
$building_info.find("#square_free").css('height', '0');
|
1331
1352
|
|
1332
|
-
|
1333
|
-
|
1334
|
-
|
1335
|
-
|
1353
|
+
// заполняем данными ссылку 'Оставить заявку'
|
1354
|
+
var $a_make_order = $building_info.find('.c80_order_invoking_btn');
|
1355
|
+
$a_make_order.data('comment-text', 'Здравствуйте, оставляю заявку на площадь: ' + area_json["title"]);
|
1356
|
+
$a_make_order.data('subj-id', area_json["id"]);
|
1357
|
+
}
|
1336
1358
|
|
1337
1359
|
};
|
1338
1360
|
|
@@ -1382,6 +1404,11 @@ var InitMap = function (params) {
|
|
1382
1404
|
|
1383
1405
|
};
|
1384
1406
|
|
1407
|
+
// взять C80MapFloors::current_floor и назначить ему sfloor.id выбранный в окне _modal_window.html.erb
|
1408
|
+
self.link_floor = function () {
|
1409
|
+
console.log('<link_floor> Связать Этаж sfloor.id=' + sfloor.id + ' с полигоном current_floor=' + current_floor + '.');
|
1410
|
+
};
|
1411
|
+
|
1385
1412
|
// взять C80MapFloors::current_building и назначить ему Rent::building.id,
|
1386
1413
|
// выбранный в окне _modal_window.html.erb
|
1387
1414
|
self.link_building = function () {
|
@@ -1394,7 +1421,7 @@ var InitMap = function (params) {
|
|
1394
1421
|
|
1395
1422
|
// извлекаем значения
|
1396
1423
|
var rent_building_id = $s.val();
|
1397
|
-
var map_building_id = self.current_building.id;
|
1424
|
+
var map_building_id = self.current_building.id; //#-> [iddqd]
|
1398
1425
|
//console.log("<Map.link_area> rent_building_id = " + rent_building_id + "; map_building_id = " + map_building_id);
|
1399
1426
|
|
1400
1427
|
// нажимаем кнопку "закрыть"
|
@@ -78,6 +78,8 @@ function StateController() {
|
|
78
78
|
case "editing":
|
79
79
|
//<editor-fold desc="...">
|
80
80
|
|
81
|
+
console.log("<StateController.setMode> <ожидается рисование полигонов Зданий>.");
|
82
|
+
|
81
83
|
// спрячем надписи "цена за метр" и адрес с телефоном
|
82
84
|
_this.left_side.css("top", -300);
|
83
85
|
_this.right_side.css("top", -300);
|
@@ -345,8 +347,8 @@ function StateController() {
|
|
345
347
|
// прячем masked слой - а там что (запомятовал)?
|
346
348
|
_this.masked.addClass('hiddn');
|
347
349
|
|
348
|
-
// скроем кнопку "связать
|
349
|
-
_map.
|
350
|
+
// скроем кнопку "связать этаж с полигоном" (которая видна при выходе из режима редактирования этажа)
|
351
|
+
_map.floor_link_button_klass.hide();
|
350
352
|
|
351
353
|
// прячем кнопку "отправить заявку на аренду площади"
|
352
354
|
_this.area_order_button.css('display', 'none');
|
@@ -376,11 +378,13 @@ function StateController() {
|
|
376
378
|
case 'edit_floor':
|
377
379
|
//<editor-fold desc="...">
|
378
380
|
|
381
|
+
console.log("<StateController.setMode> <Ожидается рисование полигонов Площадей>.");
|
382
|
+
|
379
383
|
// спрячем кнопку "обратно на карту"
|
380
384
|
_map.back_to_map_button_klass.hide();
|
381
385
|
|
382
|
-
// покажем кнопку "связать
|
383
|
-
|
386
|
+
// покажем кнопку "связать Этаж с полигоном"
|
387
|
+
_map.floor_link_button_klass.show();
|
384
388
|
|
385
389
|
// т.к. этот слой используется испключительно в помощь при рисовании обводки площадей и перехватывает клики при dnd, то тут он нам не нужен
|
386
390
|
_this.svg_overlay.css('display', 'none');
|
@@ -442,7 +442,7 @@
|
|
442
442
|
font-size: 14px;
|
443
443
|
}
|
444
444
|
|
445
|
-
&.editing, &.edit_area, &.
|
445
|
+
&.editing, &.edit_area, &.edit_floor {
|
446
446
|
background-color: #a10000;
|
447
447
|
}
|
448
448
|
}
|
@@ -499,7 +499,7 @@
|
|
499
499
|
|
500
500
|
}
|
501
501
|
|
502
|
-
&.mapplic-area-link-button, &.mapplic-building-link-button {
|
502
|
+
&.mapplic-area-link-button, &.mapplic-building-link-button, &.mapplic-floor-link-button {
|
503
503
|
border-radius: 0 0 1px 1px;
|
504
504
|
border-top: none;
|
505
505
|
background-color: #a10000;
|
@@ -1346,7 +1346,7 @@ div#map_wrapper {
|
|
1346
1346
|
|
1347
1347
|
&.editing,
|
1348
1348
|
&.edit_area,
|
1349
|
-
&.
|
1349
|
+
&.edit_floor {
|
1350
1350
|
#svg {
|
1351
1351
|
|
1352
1352
|
rect.helper {
|
@@ -12,6 +12,15 @@ module C80MapFloors
|
|
12
12
|
|
13
13
|
end
|
14
14
|
|
15
|
+
# js-кнопка "связать полигон с этажом" запрашивает список несвязанных с полигонами Этажи (указанного здания)
|
16
|
+
def fetch_unlinked_floors
|
17
|
+
Rails.logger.debug "[TRACE] <AjaxController.fetch_unlinked_floors> params = #{params}"
|
18
|
+
# [TRACE] <AjaxController.fetch_unlinked_floors> params = {"building_id"=>"1", "controller"=>"c80_map_floors/ajax", "action"=>"fetch_unlinked_floors"}
|
19
|
+
|
20
|
+
@unlinked_floors = Sfloor.unlinked_floors(params[:building_id]) # Sfloor - Этаж из host app, который еще и floor_representator
|
21
|
+
|
22
|
+
end
|
23
|
+
|
15
24
|
def fetch_unlinked_buildings
|
16
25
|
# Rails.logger.debug "<AjaxController.fetch_unlinked_buildings> params = #{params}"
|
17
26
|
|
@@ -5,7 +5,6 @@ module C80MapFloors
|
|
5
5
|
# Rails.logger.debug "<MapAjaxController.save_map_data> params = #{params}"
|
6
6
|
|
7
7
|
#{ "buildings"=>{"0"=>{"coords"=>["2496.5894495412845",...]}} }
|
8
|
-
#{ "areas"=>{"0"=>{"coords"=>["2496.5894495412845",...]}} }
|
9
8
|
|
10
9
|
# ЗДАНИЯ
|
11
10
|
# в случае успеха - вернём id созданного здания,
|
@@ -14,6 +13,18 @@ module C80MapFloors
|
|
14
13
|
# завершаем всё обновленным locations.json, который Map возьмёт
|
15
14
|
# и положит в data
|
16
15
|
|
16
|
+
# ПЛОЩАДИ
|
17
|
+
#
|
18
|
+
# как было:
|
19
|
+
# {"areas"=>{"0"=>{"id"=>"61319", "coords"=>[..], "parent_building_id"=>"2"}}}
|
20
|
+
# как стало:
|
21
|
+
# {"areas"=>{"0"=>{"id"=>"61319", "coords"=>[..], "parent_floor_id"=>"2"}}}
|
22
|
+
# ...
|
23
|
+
# INSERT INTO `c80_map_floors_areas` (`coords`, `floor_id`, `created_at`, `updated_at`) VALUES ('...', 2, '2016-12-11 05:48:33.629883', '2016-12-11 05:48:33.629883')
|
24
|
+
#
|
25
|
+
#
|
26
|
+
|
27
|
+
|
17
28
|
result = {
|
18
29
|
areas: [],
|
19
30
|
buildings: [],
|
@@ -37,7 +48,7 @@ module C80MapFloors
|
|
37
48
|
end
|
38
49
|
end
|
39
50
|
|
40
|
-
# затем создадим
|
51
|
+
# затем создадим площади
|
41
52
|
if params[:areas].present?
|
42
53
|
params[:areas].each_key do |key|
|
43
54
|
new_area_options = params[:areas][key]
|
@@ -45,7 +56,7 @@ module C80MapFloors
|
|
45
56
|
# puts "<MapAjaxController.save_map_data> new_area_options[:coords] = #{new_area_options[:coords]}"
|
46
57
|
a = C80MapFloors::Area.new({
|
47
58
|
coords: new_area_options[:coords].join(','),
|
48
|
-
|
59
|
+
floor_id: new_area_options[:parent_floor_id]
|
49
60
|
})
|
50
61
|
|
51
62
|
if a.valid?
|
@@ -22,13 +22,15 @@ module C80MapFloors
|
|
22
22
|
has_one :floor, :as => :map_floor_representator, :class_name => 'C80MapFloors::Floor', :dependent => :nullify
|
23
23
|
# after_save :update_json # NOTE:: возможно, временно
|
24
24
|
|
25
|
-
|
25
|
+
# выдать список несвязанных с полигонами Этажей (указанного здания building_id)
|
26
|
+
def self.unlinked_floors(building_id)
|
26
27
|
res = []
|
27
28
|
self.all.each do |sfloor|
|
28
29
|
unless sfloor.floor.present?
|
29
30
|
res << sfloor
|
30
31
|
end
|
31
32
|
end
|
33
|
+
Rails.logger.debug "[TRACE] <floor_representator.unlinked_floors> Кол-во несвязанных Этажей: #{res.count}."
|
32
34
|
res
|
33
35
|
end
|
34
36
|
|
@@ -21,6 +21,9 @@
|
|
21
21
|
$html = $('<a href="#" class="mapplic-area-link-button" data-placement="right" data-toggle="tooltip" title="Назначить Площадь"></a>');
|
22
22
|
$btn_layer.prepend($html);
|
23
23
|
|
24
|
+
$html = $('<a href="#" class="mapplic-floor-link-button" data-placement="right" data-toggle="tooltip" title="Назначить Этаж"></a>');
|
25
|
+
$btn_layer.prepend($html);
|
26
|
+
|
24
27
|
var $status_layer = $('.status_bar');
|
25
28
|
$html = $("<%= j render 'c80_map_floors/ajax/shared/map_creating' %>");
|
26
29
|
$status_layer.append($html);
|
@@ -0,0 +1,6 @@
|
|
1
|
+
<select id="unlinked_floors" class="selectpicker" data-style="btn-default">
|
2
|
+
<% floors.each do |floor| %>
|
3
|
+
<option value="<%= floor.id%>"><%= floor.title %></option>
|
4
|
+
<% end %>
|
5
|
+
</select>
|
6
|
+
<button type="button" id='submit_floor_link' class="btn btn-success">Сохранить</button>
|
data/config/routes.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
C80MapFloors::Engine.routes.draw do
|
2
2
|
match '/save_map_data', to: 'map_ajax#save_map_data', via: :post
|
3
3
|
match '/ajax/map_edit_buttons', :to => 'ajax#map_edit_buttons', :via => :post
|
4
|
+
|
5
|
+
match '/ajax/fetch_unlinked_floors', to: 'ajax#fetch_unlinked_floors', via: :post
|
4
6
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: c80_map_floors
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.0.
|
4
|
+
version: 0.1.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- C80609A
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-12-
|
11
|
+
date: 2016-12-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -117,6 +117,7 @@ files:
|
|
117
117
|
- app/assets/javascripts/buttons/admin_buttons/button_cancel_remove.js
|
118
118
|
- app/assets/javascripts/buttons/admin_buttons/button_complete_create.js
|
119
119
|
- app/assets/javascripts/buttons/admin_buttons/button_edit.js
|
120
|
+
- app/assets/javascripts/buttons/admin_buttons/button_floor_link.js
|
120
121
|
- app/assets/javascripts/buttons/admin_buttons/button_new.js
|
121
122
|
- app/assets/javascripts/buttons/admin_buttons/button_remove.js
|
122
123
|
- app/assets/javascripts/buttons/admin_buttons/button_save.js
|
@@ -175,12 +176,14 @@ files:
|
|
175
176
|
- app/views/c80_map_floors/_map_row_index.html.erb
|
176
177
|
- app/views/c80_map_floors/ajax/fetch_unlinked_areas.js.erb
|
177
178
|
- app/views/c80_map_floors/ajax/fetch_unlinked_buildings.js.erb
|
179
|
+
- app/views/c80_map_floors/ajax/fetch_unlinked_floors.js.erb
|
178
180
|
- app/views/c80_map_floors/ajax/map_edit_buttons.js.erb
|
179
181
|
- app/views/c80_map_floors/ajax/shared/_map_creating.html.erb
|
180
182
|
- app/views/c80_map_floors/ajax/shared/_map_editing.html.erb
|
181
183
|
- app/views/c80_map_floors/ajax/shared/_map_removing.html.erb
|
182
184
|
- app/views/c80_map_floors/ajax/shared/_select_list_unlinked_areas.html.erb
|
183
185
|
- app/views/c80_map_floors/ajax/shared/_select_list_unlinked_buildings.html.erb
|
186
|
+
- app/views/c80_map_floors/ajax/shared/_select_list_unlinked_floors.html.erb
|
184
187
|
- app/views/c80_map_floors/shared/_modal_window.html.erb
|
185
188
|
- app/views/c80_map_floors/shared/_save_preloader.html.erb
|
186
189
|
- app/views/c80_map_floors/shared/map_row/_area_order_button.html.erb
|