c80_push 0.1.0.1 → 0.1.0.2
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/README.md +34 -0
- data/app/assets/javascripts/c80_push/frontend/c80_push_page_dealers/_dealers_left_list_clicks.js +50 -0
- data/app/assets/javascripts/c80_push/frontend/c80_push_page_dealers/_dealers_left_list_filter.js +14 -0
- data/app/assets/javascripts/c80_push/frontend/c80_push_page_dealers/_map_init.js +23 -0
- data/app/assets/javascripts/c80_push/frontend/c80_push_page_dealers/_map_set_objects.js +26 -0
- data/app/assets/javascripts/c80_push/frontend/c80_push_page_dealers/_select_region_init.js +20 -0
- data/app/assets/stylesheets/c80_push/c80_push_page_dealers/_layout.scss +6 -1
- data/app/assets/stylesheets/c80_push/c80_push_page_dealers/_style.scss +14 -1
- data/app/assets/stylesheets/c80_push/c80_push_page_dealers/map_dealers_list.scss +6 -0
- data/app/helpers/c80_push/application_helper.rb +93 -0
- data/app/helpers/c80_push/page_dealers/{page_dealers_helper.rb → dealers_left_list_helper.rb} +8 -6
- data/app/models/c80_push/office.rb +4 -0
- data/app/views/c80_push/shared/_page_dealers.html.erb +8 -2
- data/app/views/c80_push/shared/_select_region.html.erb +7 -0
- data/lib/c80_push/version.rb +1 -1
- metadata +8 -3
- data/app/assets/javascripts/c80_push/frontend/c80_push_page_dealers/init_yandex_map.js +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b4d991e9e1a4d40ab4a2788f801fc5bda42e61d2
|
4
|
+
data.tar.gz: 37d7c1a99822e278f8b2b4db16255fdd29a187a8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c88589031569da99e0158285b792473c6b0c1a580106b6830ad1ffaee861546c219a760983054d5d126da6acf185fb4bdfb8060ad8c2a6eceb171381de09d5f1
|
7
|
+
data.tar.gz: 9a7b1e94d5105aed752b535222df57341519ae0e7fde738650edda28ccc362185b010eea44616551fbc6b039440b050f3d2bffdb2a59b05609be3d9bd67f595c
|
data/README.md
CHANGED
@@ -56,15 +56,49 @@ Add these lines to host app's `active_admin.js.coffee`:
|
|
56
56
|
Add these lines to host app's 'application.js.coffee':
|
57
57
|
|
58
58
|
```js
|
59
|
+
#= require bootstrap
|
60
|
+
#= require bootstrap-select
|
59
61
|
#= require c80_push
|
60
62
|
```
|
61
63
|
|
62
64
|
Add these lines to host app's 'application.scss':
|
63
65
|
|
64
66
|
```css
|
67
|
+
@import "bootstrap-sprockets";
|
68
|
+
@import "bootstrap";
|
69
|
+
@import "bootstrap-select";
|
65
70
|
@include "c80_push";
|
66
71
|
```
|
67
72
|
|
73
|
+
## Процесс разработки JS функционала
|
74
|
+
|
75
|
+
Теперь пора заняться js.
|
76
|
+
|
77
|
+
* [X] Прикрутить `selectpicker`: выводить туда только те регионы, в которых есть дилеры,
|
78
|
+
у которых есть офисы.
|
79
|
+
|
80
|
+
* [X] Вставить заголовок "Выберите Регион".
|
81
|
+
|
82
|
+
* [X] При первом входе на карту: должны отражаться все офисы.
|
83
|
+
|
84
|
+
- [X] Должен рассчитываться `bounding rectangle` и все точки должны быть видны
|
85
|
+
на рабочей области (никто не должен выходить за рамки)
|
86
|
+
|
87
|
+
* [ ] При наведении/клике на точку на карте:
|
88
|
+
|
89
|
+
- [X] должен появляться хинт с деталями офиса
|
90
|
+
- [ ] слева должен подсвечиваться соответствующий `.li_office`.
|
91
|
+
|
92
|
+
* [X] При наведении/клике на `.li_office` - должна подсвечиваться соответствующая
|
93
|
+
точка на карте.
|
94
|
+
|
95
|
+
* [ ] Вставить из `psd` синий маркер.
|
96
|
+
|
97
|
+
* [X] Когда меняется регион:
|
98
|
+
|
99
|
+
* [X] Должны отобразиться релевантные `.li_office`
|
100
|
+
* [X] Должны отобразиться релевантные точки на карте.
|
101
|
+
|
68
102
|
## Цитата из ТЗ
|
69
103
|
|
70
104
|
> Данный раздел представляет собой список компаний, у которых указаны
|
data/app/assets/javascripts/c80_push/frontend/c80_push_page_dealers/_dealers_left_list_clicks.js
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
/**
|
2
|
+
* Сфокусироваться на точке на карте.
|
3
|
+
* Если надо - открыть balloon.
|
4
|
+
* @param id : id офиса.
|
5
|
+
*/
|
6
|
+
function _item_toggle(id) {
|
7
|
+
//console.log('<_item_toggle> id: ' + id);
|
8
|
+
|
9
|
+
var it = dealers_map.geoObjects.getIterator(),
|
10
|
+
group;
|
11
|
+
|
12
|
+
while(group = it.getNext()) {
|
13
|
+
//console.log(group.properties);
|
14
|
+
if (group.properties !== undefined) {
|
15
|
+
for (var i = 0, len = group.getLength(); i < len; i++) {
|
16
|
+
var placemark = group.get(i);
|
17
|
+
//console.log(placemark.properties.get('id'));
|
18
|
+
if (placemark.properties.get('id') === id) {
|
19
|
+
//console.log('+ ' + placemark.balloon.isOpen());
|
20
|
+
if (placemark.balloon.isOpen()) {
|
21
|
+
placemark.balloon.close();
|
22
|
+
}
|
23
|
+
else {
|
24
|
+
dealers_map.panTo(placemark.geometry.getCoordinates(), {
|
25
|
+
delay: 0
|
26
|
+
}).then(function () {
|
27
|
+
placemark.balloon.open();
|
28
|
+
});
|
29
|
+
}
|
30
|
+
return;
|
31
|
+
}
|
32
|
+
}
|
33
|
+
break;
|
34
|
+
}
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
/**
|
39
|
+
* Начинаем слушать клики по .li_office.
|
40
|
+
* При клике - вызовется _item_toggle.
|
41
|
+
*/
|
42
|
+
function _dealers_left_list_clicks() {
|
43
|
+
$('.li_office').on("click", function (e) {
|
44
|
+
e.preventDefault();
|
45
|
+
var office_id = $(this).data('id');
|
46
|
+
_item_toggle(office_id);
|
47
|
+
});
|
48
|
+
}
|
49
|
+
|
50
|
+
$(document).ready(_dealers_left_list_clicks);
|
data/app/assets/javascripts/c80_push/frontend/c80_push_page_dealers/_dealers_left_list_filter.js
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
/**
|
2
|
+
* В списке дилеров слева от карты оставить только тех,
|
3
|
+
* кто принадлежит указанному региону.
|
4
|
+
*
|
5
|
+
* @param region_id
|
6
|
+
*/
|
7
|
+
function dealers_left_list_filter(region_id) {
|
8
|
+
if (region_id === 'all') {
|
9
|
+
$('.li_region').css('display', 'block');
|
10
|
+
} else {
|
11
|
+
$('.li_region').css('display', 'none');
|
12
|
+
$('.li_region#region_' + region_id).css('display','block');
|
13
|
+
}
|
14
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
var dealers_map;
|
4
|
+
|
5
|
+
$(document).ready(function() {
|
6
|
+
|
7
|
+
if ($('#dealers_map_container').length) {
|
8
|
+
//noinspection JSUnresolvedVariable
|
9
|
+
ymaps.ready(function() {
|
10
|
+
|
11
|
+
//noinspection JSUnresolvedVariable,JSUnresolvedFunction
|
12
|
+
dealers_map = new ymaps.Map('dealers_map_container', {
|
13
|
+
center: [55, 37],
|
14
|
+
zoom: 10,
|
15
|
+
controls: ['zoomControl']
|
16
|
+
});
|
17
|
+
|
18
|
+
map_set_objects('all');
|
19
|
+
|
20
|
+
});
|
21
|
+
}
|
22
|
+
|
23
|
+
});
|
@@ -0,0 +1,26 @@
|
|
1
|
+
// нарисовать на карте объекты из указанного
|
2
|
+
// хэша offices[region_id]
|
3
|
+
|
4
|
+
function map_set_objects(region_id) {
|
5
|
+
|
6
|
+
var arr = offices[region_id];
|
7
|
+
// console.log(arr);
|
8
|
+
var n = arr['count'];
|
9
|
+
|
10
|
+
// соберём коллекцию точек
|
11
|
+
var c = new ymaps.GeoObjectCollection();
|
12
|
+
var icoords, iprops; // loop vars
|
13
|
+
for (var i = 0; i < n; i++) {
|
14
|
+
icoords = arr['coords'][i];
|
15
|
+
iprops = arr['props'][i];
|
16
|
+
c.add(new ymaps.Placemark(icoords, iprops));
|
17
|
+
}
|
18
|
+
|
19
|
+
// сначала уберём все точки
|
20
|
+
dealers_map.geoObjects.each(function(o) {
|
21
|
+
dealers_map.geoObjects.remove(o)
|
22
|
+
});
|
23
|
+
|
24
|
+
dealers_map.geoObjects.add(c);
|
25
|
+
dealers_map.setBounds(c.getBounds());
|
26
|
+
}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
var $select_region;
|
2
|
+
|
3
|
+
/**
|
4
|
+
* Когда меняется регион:
|
5
|
+
* - Должны отобразиться релевантные `.li_office`
|
6
|
+
* - Должны отобразиться релевантные точки на карте.
|
7
|
+
*/
|
8
|
+
var _select_region_on_change = function() {
|
9
|
+
var region_id = $(this).val();
|
10
|
+
// console.log('<_select_region_on_change> region_id = ' + region_id);
|
11
|
+
map_set_objects(region_id);
|
12
|
+
dealers_left_list_filter(region_id);
|
13
|
+
};
|
14
|
+
|
15
|
+
var select_region_init = function() {
|
16
|
+
//noinspection JSUnresolvedFunction
|
17
|
+
$select_region = $('#select_region').selectpicker();
|
18
|
+
$select_region.change(_select_region_on_change);
|
19
|
+
};
|
20
|
+
$(document).ready(select_region_init);
|
@@ -5,9 +5,22 @@ div.c80_push_page_dealers {
|
|
5
5
|
|
6
6
|
div.select_region_row {
|
7
7
|
background-color: #E0001A;
|
8
|
+
div.select_wrapper {
|
9
|
+
|
10
|
+
}
|
8
11
|
}
|
9
12
|
|
10
|
-
div
|
13
|
+
div.bottom_row {
|
14
|
+
|
15
|
+
> div {
|
16
|
+
}
|
17
|
+
|
18
|
+
div.dealers_list {
|
19
|
+
background-color: #f5f5f5;
|
20
|
+
}
|
21
|
+
|
22
|
+
div#dealers_map_container {
|
23
|
+
}
|
11
24
|
|
12
25
|
}
|
13
26
|
|
@@ -2,6 +2,8 @@
|
|
2
2
|
margin: 0;
|
3
3
|
padding: 0;
|
4
4
|
list-style: none;
|
5
|
+
border-top: 1px #B2B2B2 solid;
|
6
|
+
background-color: #ffffff;
|
5
7
|
|
6
8
|
.li_region {
|
7
9
|
|
@@ -16,6 +18,8 @@
|
|
16
18
|
padding: 0; //5px 5px 10px 15px;
|
17
19
|
list-style: none;
|
18
20
|
border: 1px #B2B2B2 solid;
|
21
|
+
border-bottom: none;
|
22
|
+
border-top: none;
|
19
23
|
|
20
24
|
.li_dealer {
|
21
25
|
padding: 15px;
|
@@ -74,6 +78,7 @@
|
|
74
78
|
|
75
79
|
&:hover {
|
76
80
|
border-bottom: 1px transparent solid;
|
81
|
+
z-index: 1;
|
77
82
|
&:after {
|
78
83
|
display: block;
|
79
84
|
background-color: #e8e8e8;
|
@@ -84,6 +89,7 @@
|
|
84
89
|
border-bottom: 1px transparent solid;
|
85
90
|
color: #e4e0e0;
|
86
91
|
position: relative;
|
92
|
+
z-index: 1;
|
87
93
|
|
88
94
|
&:after {
|
89
95
|
display: block;
|
@@ -6,10 +6,103 @@ module C80Push
|
|
6
6
|
module ApplicationHelper
|
7
7
|
|
8
8
|
def c80_push_render_page_dealers
|
9
|
+
|
10
|
+
# список регионов, включая дилеры и офисы
|
11
|
+
region_dealer_office_list = Region.includes(dealers: :offices)
|
12
|
+
|
13
|
+
# хэш для построения точек на Yandex карте
|
14
|
+
ymap_hash = prepare_ymap_hash(region_dealer_office_list)
|
15
|
+
|
16
|
+
# список регионов для select-а "Выберите регион"
|
17
|
+
r = prepare_regions_hash(region_dealer_office_list)
|
18
|
+
|
9
19
|
render partial: 'c80_push/shared/page_dealers',
|
10
20
|
locals: {
|
21
|
+
rdo_list: region_dealer_office_list,
|
22
|
+
regions_list: r,
|
23
|
+
ymap_hash: ymap_hash
|
11
24
|
}
|
12
25
|
end
|
13
26
|
|
27
|
+
private
|
28
|
+
|
29
|
+
# специально для яваскрипта, работающего с yandex картой,
|
30
|
+
# на основе +rdo+ собираем координаты всех офисов
|
31
|
+
# в хеше вида:
|
32
|
+
#
|
33
|
+
# {
|
34
|
+
# all: { - здесь собираем все офисы всех регионов (для лаконичности js)
|
35
|
+
# coords: [],
|
36
|
+
# props: []
|
37
|
+
# }
|
38
|
+
# <region_id>: [ - данные офисов разложены по регионам
|
39
|
+
# coords: [],
|
40
|
+
# props: []
|
41
|
+
# ]
|
42
|
+
# }
|
43
|
+
#
|
44
|
+
# noinspection RubyResolve
|
45
|
+
def prepare_ymap_hash(rdo)
|
46
|
+
res = {
|
47
|
+
all: {
|
48
|
+
coords: [],
|
49
|
+
props: []
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
rdo.each do |region|
|
54
|
+
region.dealers.each do |dealer|
|
55
|
+
dealer.offices.each do |office|
|
56
|
+
res[region.id] = { coords:[], props:[] } if res[region.id].nil?
|
57
|
+
|
58
|
+
# координаты точки (это массив двух точек)
|
59
|
+
gps = office.gps_arr
|
60
|
+
|
61
|
+
# соберём свойства офиса для балуна
|
62
|
+
props = {
|
63
|
+
balloonContentHeader: t = "#{office.title} (#{dealer.title})",
|
64
|
+
balloonContentBody: b = "#{office.addr}<br>#{office.tel}<br>GPS: #{office.gps}",
|
65
|
+
hintContent: "#{t}<br>#{b}",
|
66
|
+
id: office.id
|
67
|
+
}
|
68
|
+
|
69
|
+
# фиксируем в хэше региона
|
70
|
+
res[region.id][:coords] << gps
|
71
|
+
res[region.id][:props] << props
|
72
|
+
|
73
|
+
# фиксируем в all-хэше
|
74
|
+
res[:all][:coords] << gps
|
75
|
+
res[:all][:props] << props
|
76
|
+
|
77
|
+
end
|
78
|
+
# для удобства в js: зафиксируем кол-во офисов региона
|
79
|
+
res[region.id][:count] = res[region.id][:coords].size
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# для удобства в js: зафиксируем кол-во всех офисов
|
84
|
+
res[:all][:count] = res[:all][:coords].size
|
85
|
+
|
86
|
+
res
|
87
|
+
end
|
88
|
+
|
89
|
+
# соберёт хэш только тех регионов, в которых есть офисы
|
90
|
+
# например: {4=>{:id=>4, :title=>"Санкт-Петербург"}}
|
91
|
+
def prepare_regions_hash(rdo)
|
92
|
+
res = {}
|
93
|
+
rdo.each do |region|
|
94
|
+
region.dealers.each do |dealer|
|
95
|
+
dealer.offices.each do |office|
|
96
|
+
if res[region.id].nil?
|
97
|
+
res[region.id] = { id:region.id, title:region.title }
|
98
|
+
else
|
99
|
+
break
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
res
|
105
|
+
end
|
106
|
+
|
14
107
|
end
|
15
108
|
end
|
data/app/helpers/c80_push/page_dealers/{page_dealers_helper.rb → dealers_left_list_helper.rb}
RENAMED
@@ -1,12 +1,14 @@
|
|
1
1
|
module C80Push
|
2
2
|
module PageDealers
|
3
|
-
module
|
3
|
+
module DealersLeftListHelper
|
4
4
|
|
5
|
-
# Выдать
|
6
|
-
# разложенный по
|
5
|
+
# Выдать html unordered nested list Дилеров (включая Офисы),
|
6
|
+
# разложенный по Регионам, построенный
|
7
|
+
# на основе данных +rdo+ - Regions-Dealers-Offices.
|
7
8
|
# Список выводится слева от карты.
|
8
9
|
# (**) Не выводим регионы, у которых нет дилеров.
|
9
10
|
#
|
11
|
+
# Структура списка:
|
10
12
|
# * Регион
|
11
13
|
# * Дилер
|
12
14
|
# * Офис 1
|
@@ -18,11 +20,11 @@ module C80Push
|
|
18
20
|
# * сайт дилера
|
19
21
|
# * email дилера
|
20
22
|
#
|
21
|
-
def render_ul_dealers_list
|
23
|
+
def render_ul_dealers_list(rdo)
|
22
24
|
|
23
25
|
res = ''
|
24
26
|
|
25
|
-
|
27
|
+
rdo.each do |region|
|
26
28
|
r = "<h2 class='region_title'>#{region.title}</h2>"
|
27
29
|
ds = ul_region_dealers(region)
|
28
30
|
next if ds.blank? # (**)
|
@@ -57,7 +59,7 @@ module C80Push
|
|
57
59
|
dealer.offices.each_with_index do |office|
|
58
60
|
o = "<h4 class='office_title'>#{office.title}</h4>"
|
59
61
|
o += ul_office_props(office)
|
60
|
-
res += "<li class='li_office' id='office_#{office.id}'>#{o}</li>"
|
62
|
+
res += "<li class='li_office' id='office_#{office.id}' data-id='#{office.id}'>#{o}</li>"
|
61
63
|
end
|
62
64
|
res += "<li class='dealer_email'>#{dealer.email}</li>"
|
63
65
|
res += "<li class='dealer_site'>#{dealer.site}</li>"
|
@@ -1,13 +1,15 @@
|
|
1
1
|
<div class="c80_push_page_dealers">
|
2
2
|
|
3
3
|
<div class="select_region_row">
|
4
|
-
|
4
|
+
<div class="select_wrapper">
|
5
|
+
<%= render 'c80_push/shared/select_region', regions: regions_list %>
|
6
|
+
</div>
|
5
7
|
</div>
|
6
8
|
|
7
9
|
<div class="bottom_row">
|
8
10
|
|
9
11
|
<div class="dealers_list">
|
10
|
-
<%= render_ul_dealers_list %>
|
12
|
+
<%= render_ul_dealers_list(rdo_list) %>
|
11
13
|
</div>
|
12
14
|
|
13
15
|
<div id="dealers_map_container">
|
@@ -18,4 +20,8 @@
|
|
18
20
|
|
19
21
|
</div>
|
20
22
|
|
23
|
+
<script>
|
24
|
+
var offices = <%= ymap_hash.to_json.html_safe %>;
|
25
|
+
</script>
|
26
|
+
|
21
27
|
<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU" type="text/javascript"></script>
|
@@ -0,0 +1,7 @@
|
|
1
|
+
<select id='select_region' class="selectpicker" data-width="400px" data-size="10">
|
2
|
+
<option value="all">Выберите регион</option>
|
3
|
+
<% regions.each_key do |k| %>
|
4
|
+
<% region = regions[k] %>
|
5
|
+
<option value="<%= region[:id] %>"><%= region[:title] %></option>
|
6
|
+
<% end %>
|
7
|
+
</select>
|
data/lib/c80_push/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: c80_push
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.0.
|
4
|
+
version: 0.1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- C80609A
|
@@ -40,7 +40,11 @@ files:
|
|
40
40
|
- app/assets/config/c80_push_manifest.js
|
41
41
|
- app/assets/javascripts/c80_push.js.coffee
|
42
42
|
- app/assets/javascripts/c80_push/backend/dealers.js
|
43
|
-
- app/assets/javascripts/c80_push/frontend/c80_push_page_dealers/
|
43
|
+
- app/assets/javascripts/c80_push/frontend/c80_push_page_dealers/_dealers_left_list_clicks.js
|
44
|
+
- app/assets/javascripts/c80_push/frontend/c80_push_page_dealers/_dealers_left_list_filter.js
|
45
|
+
- app/assets/javascripts/c80_push/frontend/c80_push_page_dealers/_map_init.js
|
46
|
+
- app/assets/javascripts/c80_push/frontend/c80_push_page_dealers/_map_set_objects.js
|
47
|
+
- app/assets/javascripts/c80_push/frontend/c80_push_page_dealers/_select_region_init.js
|
44
48
|
- app/assets/javascripts/c80_push/lib_backend/init.js
|
45
49
|
- app/assets/javascripts/c80_push/lib_backend/init_select_picker.js
|
46
50
|
- app/assets/javascripts/c80_push_backend.js.coffee
|
@@ -51,12 +55,13 @@ files:
|
|
51
55
|
- app/assets/stylesheets/c80_push_backend.scss
|
52
56
|
- app/helpers/c80_push/admin_helper.rb
|
53
57
|
- app/helpers/c80_push/application_helper.rb
|
54
|
-
- app/helpers/c80_push/page_dealers/
|
58
|
+
- app/helpers/c80_push/page_dealers/dealers_left_list_helper.rb
|
55
59
|
- app/models/c80_push/application_record.rb
|
56
60
|
- app/models/c80_push/dealer.rb
|
57
61
|
- app/models/c80_push/office.rb
|
58
62
|
- app/models/c80_push/region.rb
|
59
63
|
- app/views/c80_push/shared/_page_dealers.html.erb
|
64
|
+
- app/views/c80_push/shared/_select_region.html.erb
|
60
65
|
- config/locales/dealer/ru.yml
|
61
66
|
- config/locales/office/ru.yml
|
62
67
|
- config/locales/region/ru.yml
|