admin_it 1.2.5 → 1.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8261d9f5d210ee88e9fd0451865fd20595e55e9d
4
- data.tar.gz: 725141e13c0a686cdca30e5d098c53c5ae25f30e
3
+ metadata.gz: 59e741cf6aa0a6d0b798342724be6d44273202fa
4
+ data.tar.gz: c2e371c65ed2f758a74f12c63ea7cb0af0835200
5
5
  SHA512:
6
- metadata.gz: 8cd3f0450666f047996c99895553fee547db7396d16862a3f49f45e657fbe52b71e29e1098e44c45048154af9277da3c573c967607b3acbd5f5d9c59c5a0d5de
7
- data.tar.gz: 109f2522c4c74015807a502620ae4d578164e0c290719f1483d97e22eaeb78a23128c1c6c30948fbcd3de44ab612ab7ebe9d6a870ff5c96a62ef866f903bf0b4
6
+ metadata.gz: c85697942c88f327fd1079832ccdb1314c87ff8ecdff949e86c814c042b544f9075bfb5b730b484a288fad7bee9c1e7072a79ea3cfedd4c46d9b7c0cf6f56760
7
+ data.tar.gz: 61400cb10f7c364b000765ce7e3e393f641d01040ae068284adb37d076fade4a42cecd625a58457b127c8981c79b689e6104ef294b1988e9d5688e282c7ce907
data/README.md CHANGED
@@ -36,7 +36,10 @@ bundle install
36
36
 
37
37
  # Changes
38
38
 
39
- `1.2.4`
39
+ `1.2.6`
40
+ * added: geo location picker
41
+
42
+ `1.2.5`
40
43
  * fixed: Content-Length in production environment for UTF-8
41
44
 
42
45
  `1.2.4`
@@ -126,6 +126,35 @@ var initSelects = function() {
126
126
  });
127
127
  }
128
128
 
129
+ var initGeoPickers = function() {
130
+ $('[data-geo-picker]').each(function() {
131
+ var $this = $(this);
132
+ var $input = $($this.data('geoPicker'));
133
+ var arr = $input.val().split(',');
134
+ var lon = parseFloat(arr[0]);
135
+ var lat = parseFloat(arr[1]);
136
+ $this.geoLocationPicker({
137
+ gMapZoom: 13,
138
+ gMapMapTypeId: google.maps.MapTypeId.ROADMAP,
139
+ gMapMarkerTitle: 'Выбирите местоположение',
140
+ showPickerEvent: 'click',
141
+ defaultLat: lat || 55.751607, // center
142
+ defaultLng: lon || 37.617159, // of Moscow
143
+ defaultLocationCallback: function(lat, lon) {
144
+ $input.val(lon + ', ' + lat);
145
+ $input.parent().find('.x').text(lon);
146
+ $input.parent().find('.y').text(lat);
147
+ }
148
+ });
149
+ });
150
+ }
151
+
152
+ var initControls = function() {
153
+ initImageUploads();
154
+ initSelects();
155
+ initGeoPickers();
156
+ }
157
+
129
158
  $(document).on('ready page:load', function() {
130
159
  initPartials();
131
160
  // initDialogs();
@@ -133,8 +162,7 @@ $(document).on('ready page:load', function() {
133
162
  initTabs();
134
163
  initPopups();
135
164
  initLinks();
136
- initImageUploads();
137
- initSelects();
165
+ initControls();
138
166
  // allow dialog content reloading
139
167
  $('.modal').on('hidden.bs.modal', function() { $(this).removeData(); })
140
168
  .on('loaded.bs.modal', function() {
@@ -150,7 +178,6 @@ $(document).on('ready page:load', function() {
150
178
  $form.submit();
151
179
  });
152
180
  }
153
- initImageUploads();
154
- initSelects();
181
+ initControls();
155
182
  })
156
183
  });
@@ -5,5 +5,6 @@
5
5
  //= require admin_it/jquery.fileupload
6
6
  //= require admin_it/jquery.fileupload-ui
7
7
  //= require admin_it/jquery.fileupload-process
8
+ //= require admin_it/jquery.geolocationpicker.js
8
9
  //= require select2
9
10
  //= require admin_it/admin_it
@@ -0,0 +1,200 @@
1
+ // Source: https://github.com/liskiew/jquery-geolocation-picker
2
+ (function($) {
3
+
4
+ //Attach this new method to jQuery
5
+ $.fn.extend({
6
+
7
+ //This is where you write your plugin's name
8
+ geoLocationPicker: function(options) {
9
+
10
+ var geocoder = new google.maps.Geocoder();
11
+
12
+ var settings = {
13
+ width: "300px",
14
+ height: "200px",
15
+ backgroundColor: '#fff',
16
+ border: '1px solid #ccc',
17
+ borderRadius: 10,
18
+ padding: 10,
19
+ defaultLat: 52.229683, // Warsaw, Poland
20
+ defaultLng: 21.012175, // Warsaw, Poland
21
+ gMapMapTypeId: google.maps.MapTypeId.HYBRID,
22
+ gMapZoom: 15,
23
+ gMapMapTypeControl: false,
24
+ gMapDisableDoubleClickZoom: true,
25
+ gMapStreetViewControl: false,
26
+ gMapMarkerTitle: "Here I am.",
27
+ showPickerEvent: "focus",
28
+ left: options.left,
29
+ top: options.top
30
+ };
31
+
32
+ function RoundDecimal(num, decimals) {
33
+ var mag = Math.pow(10, decimals);
34
+ return Math.round(num * mag) / mag;
35
+ }
36
+
37
+
38
+ return this.each(function() {
39
+
40
+ var _this = this;
41
+ // merge default settings with options and default callback method
42
+ settings = $.extend({
43
+ defaultAddressCallback: function() { return $(_this).val();},
44
+ defaultLocationCallback: function(lat, lng) {$(_this).val(lat + "," + lng);}
45
+ }, settings, options);
46
+
47
+ var visible = false;
48
+ var id = $(this).attr('id');
49
+ var pickerId = "picker-" + id;
50
+ var mapDivId = "mapdiv-" + id;
51
+
52
+ var picker = $("<div id='" + pickerId + "' class='picker-map'></div>").css({
53
+ width: settings.width,
54
+ backgroundColor: settings.backgroundColor,
55
+ border: settings.border,
56
+ padding: settings.padding,
57
+ borderRadius: settings.borderRadius,
58
+ position: "absolute",
59
+ display: "none",
60
+ left: settings.left,
61
+ top: settings.top,
62
+ 'z-index': 1
63
+ });
64
+
65
+ var mapDiv = $("<div class='picker-map-div' id='" + mapDivId + "'>Loading</div>").css({
66
+ height: settings.height
67
+ });
68
+
69
+
70
+ $(this).after(picker);
71
+ picker.append(mapDiv);
72
+
73
+
74
+ var defaultLocationLatLng = new google.maps.LatLng(settings.defaultLat, settings.defaultLng);
75
+ // $(_this).val(lat + "," + lng);<
76
+
77
+ var gMapOptions = {
78
+ zoom: settings.gMapZoom,
79
+ center: defaultLocationLatLng,
80
+ mapTypeId: settings.gMapMapTypeId,
81
+ mapTypeControl: settings.gMapMapTypeControl,
82
+ disableDoubleClickZoom: settings.gMapDisableDoubleClickZoom,
83
+ streetViewControl: settings.gMapStreetViewControl
84
+ };
85
+
86
+ var map = new google.maps.Map(mapDiv.get(0), gMapOptions);
87
+
88
+ var marker = new google.maps.Marker({
89
+ title: settings.gMapMarkerTitle,
90
+ map: map,
91
+ position: defaultLocationLatLng,
92
+ draggable: true
93
+ });
94
+
95
+
96
+ google.maps.event.addListener(map, 'dblclick', function(event) {
97
+ setPosition(event.latLng);
98
+ });
99
+
100
+ google.maps.event.addListener(marker, 'dragend', function(event) {
101
+ setPosition(marker.position);
102
+ });
103
+
104
+
105
+ var setPosition = function(latLng, viewport) {
106
+ var lat = RoundDecimal(latLng.lat(), 6);
107
+ var lng = RoundDecimal(latLng.lng(), 6);
108
+
109
+ marker.setPosition(latLng);
110
+
111
+ if (viewport) {
112
+ map.fitBounds(viewport);
113
+ map.setZoom(map.getZoom() + 2);
114
+ } else {
115
+ map.panTo(latLng);
116
+ }
117
+
118
+ settings.defaultLocationCallback(lat, lng);
119
+ };
120
+
121
+
122
+ function getCurrentPosition() {
123
+
124
+ var posStr = $(_this).val();
125
+
126
+ if (posStr != "") {
127
+ var posArr = posStr.split(",");
128
+ if (posArr.length == 2) {
129
+ var lat = $.trim(posArr[0]);
130
+ var lng = $.trim(posArr[1]);
131
+ var latlng = new google.maps.LatLng(lat, lng);
132
+ setPosition(latlng);
133
+ return;
134
+
135
+ }
136
+ }
137
+
138
+ resolveAddress();
139
+
140
+ }
141
+
142
+ function resolveAddress(){
143
+ var address = "";
144
+
145
+ // try to call callback function for default address
146
+ if (settings.defaultAddressCallback != null) {
147
+ address = settings.defaultAddressCallback();
148
+ }
149
+ geocoder.geocode({'address': address},
150
+ function(results, status) {
151
+ if (status == google.maps.GeocoderStatus.OK) {
152
+ setPosition(results[0].geometry.location, results[0].geometry.viewport );
153
+ }
154
+ }
155
+ );
156
+ }
157
+
158
+ function hidePicker() {
159
+ picker.fadeOut('fast');
160
+ visible = false;
161
+ }
162
+
163
+ function showPicker() {
164
+ picker.fadeIn('fast');
165
+ google.maps.event.trigger(map, 'resize');
166
+ getCurrentPosition();
167
+ map.setCenter(marker.position);
168
+ visible = true;
169
+ }
170
+
171
+ $(_this).keydown(function(event) {
172
+ if (event.keyCode == '13' || event.keyCode == '10') { // enter
173
+ resolveAddress();
174
+ }
175
+ });
176
+
177
+ $(_this).bind(settings.showPickerEvent, function(event) {
178
+ if (!visible) {
179
+ showPicker();
180
+ }
181
+ event.stopPropagation();
182
+ });
183
+
184
+ $('html').click(function() {
185
+ hidePicker();
186
+ });
187
+
188
+ $(picker).click(function(event) {
189
+ event.stopPropagation();
190
+ });
191
+ $(_this).click(function(event) {
192
+ event.stopPropagation();
193
+ });
194
+ });
195
+
196
+ }
197
+
198
+ });
199
+
200
+ })(jQuery);
@@ -0,0 +1,14 @@
1
+ - for_context ||= context
2
+ - name ||= "#{for_context.resource.name}[#{field.name}]"
3
+ - id ||= "#{for_context.resource.name}_#{field.name}"
4
+ - value ||= field.read(for_context.entity)
5
+
6
+ span
7
+ input type="hidden" id=id name=name value=field.show(for_context.entity)
8
+ = t('admin_it.longtitude') + ': '
9
+ span.x = value.respond_to?(:x) ? value.x : ''
10
+ = ', ' + t('admin_it.latitude') + ': '
11
+ span.y = value.respond_to?(:y) ? value.y : ''
12
+
13
+ .btn.btn-warning.pull-right data-geo-picker="##{id}"
14
+ i.fa.fa-globe
@@ -4,23 +4,12 @@ html
4
4
  title Admin
5
5
  meta charset="utf-8"
6
6
  = csrf_meta_tags
7
-
8
- /= stylesheet_link_tag 'admin_it/bootstrap.min', media: 'all'
9
- /= stylesheet_link_tag 'admin_it/font-awesome.min', media: 'all'
10
- /= stylesheet_link_tag 'admin_it/admin_it', media: 'all'
11
- /= javascript_include_tag 'jquery', 'jquery_ujs'
12
- /= javascript_include_tag 'admin_it/bootstrap.min'
13
-
14
- / JQuery FileUpload
15
- /= stylesheet_link_tag 'admin_it/jquery.fileupload'
16
- /= stylesheet_link_tag 'admin_it/jquery.fileupload-ui'
17
- /= javascript_include_tag 'admin_it/jquery.ui.widget'
18
- /= javascript_include_tag 'admin_it/jquery.fileupload'
19
- /= javascript_include_tag 'admin_it/jquery.fileupload-ui'
20
- /= javascript_include_tag 'admin_it/jquery.fileupload-process'
21
-
22
7
  = stylesheet_link_tag 'admin_it/index', media: 'all'
23
8
  = javascript_include_tag 'admin_it/index'
9
+ - unless AdminIt.config.google_maps_key.nil?
10
+ = javascript_include_tag(raw( \
11
+ "//maps.googleapis.com/maps/api/js?" \
12
+ "key=#{AdminIt.config.google_maps_key}&sensor=false"))
24
13
  = yield :head
25
14
 
26
15
  body style="padding-top: 70px"
@@ -30,5 +30,13 @@ module AdminIt
30
30
  fail ArgumentError, 'Wrong S3 options' unless value.is_a?(Hash)
31
31
  @s3 = value
32
32
  end
33
+
34
+ def self.google_maps_key
35
+ @google_maps_key
36
+ end
37
+
38
+ def self.google_maps_key=(value)
39
+ @google_maps_key = value
40
+ end
33
41
  end
34
42
  end
@@ -20,21 +20,21 @@ module AdminIt
20
20
  protected
21
21
 
22
22
  def read_value(entity)
23
- value = entity.send(name)
24
23
  if type == :relation
24
+ value = entity.send(name)
25
25
  if assoc.collection?
26
26
  value.nil? || value.empty? ? [] : value.map(&:id).to_json
27
27
  else
28
28
  value.nil? ? nil : value.id
29
29
  end
30
30
  else
31
- value
31
+ super(entity)
32
32
  end
33
33
  end
34
34
 
35
35
  def show_value(entity)
36
- value = entity.send(name)
37
36
  if type == :relation
37
+ value = entity.send(name)
38
38
  resource = AdminIt.resources.values.find do |r|
39
39
  r.entity_class == assoc.klass
40
40
  end
@@ -51,10 +51,8 @@ module AdminIt
51
51
  else
52
52
  context.read(value)
53
53
  end
54
- elsif type == :enum
55
- value.text
56
54
  else
57
- value
55
+ super(entity)
58
56
  end
59
57
  end
60
58
 
@@ -65,8 +63,10 @@ module AdminIt
65
63
  else
66
64
  value = assoc.klass.find(value)
67
65
  end
66
+ entity.send("#{name}=", value)
67
+ else
68
+ super(entity, value)
68
69
  end
69
- entity.send("#{name}=", value)
70
70
  end
71
71
  end
72
72
  end
@@ -40,15 +40,7 @@ module AdminIt
40
40
 
41
41
  #
42
42
  module Field
43
- protected
44
-
45
- def read_value(entity)
46
- entity.send(name)
47
- end
48
-
49
- def write_value(entity, value)
50
- entity.send("#{name}=", value)
51
- end
43
+ # protected
52
44
  end
53
45
  end
54
46
  end
@@ -19,8 +19,8 @@ module AdminIt
19
19
  include ExtendIt::Callbacks
20
20
 
21
21
  TYPES = %i(unknown integer float string date datetime time relation enum
22
- array hash range regexp symbol binary image)
23
- EDITORS = %i(text combo radio image hidden)
22
+ array hash range regexp symbol binary image geo_point)
23
+ EDITORS = %i(text combo radio image hidden geo_picker)
24
24
 
25
25
  define_callbacks :initialize
26
26
 
@@ -116,6 +116,7 @@ module AdminIt
116
116
  return @editor unless @editor.nil?
117
117
  return @editor = :image if type == :image
118
118
  return @editor = :combo if type == :enum
119
+ return @editor = :geo_picker if type == :geo_point
119
120
  @editor = EDITORS[0]
120
121
  end
121
122
 
@@ -209,22 +210,45 @@ module AdminIt
209
210
 
210
211
  protected
211
212
 
212
- def read_value(entity)
213
- fail NotImplementedError,
214
- "Attempt to read field #{name} with unimplemented reader"
215
- end
213
+ # def read_value(entity)
214
+ # fail NotImplementedError,
215
+ # "Attempt to read field #{name} with unimplemented reader"
216
+ # end
217
+ #
218
+ # def show_value(entity)
219
+ # fail NotImplementedError,
220
+ # "Attempt to show field #{name} with unimplemented show method"
221
+ # end
222
+ #
223
+ # def write_value(entity, value)
224
+ # fail NotImplementedError,
225
+ # "Attempt to write to field #{name} with unimplemented writer"
226
+ # end
216
227
 
217
228
  def show_value(entity)
229
+ value = read_value(entity)
218
230
  if type == :enum
219
- entity.send(name).text
231
+ value.text
232
+ elsif type == :geo_point
233
+ value.nil? ? '' : "#{value.x}, #{value.y}"
220
234
  else
221
- read_value(entity)
235
+ value
222
236
  end
223
237
  end
224
238
 
239
+ def read_value(entity)
240
+ entity.send(name)
241
+ end
242
+
225
243
  def write_value(entity, value)
226
- fail NotImplementedError,
227
- "Attempt to write to field #{name} with unimplemented writer"
244
+ if type == :geo_point
245
+ point = entity.send(name)
246
+ x, y = value.split(',', 2)
247
+ factory = entity_class.const_get(:FACTORY, true)
248
+ point = factory.point(x.to_f, y.to_f)
249
+ value = point
250
+ end
251
+ entity.send("#{name}=", value)
228
252
  end
229
253
  end
230
254
 
@@ -15,6 +15,8 @@ en:
15
15
  filters: 'Filters'
16
16
  details: 'Details'
17
17
  destroying: 'Deletion'
18
+ latitude: 'Latitude'
19
+ longtitude: 'Longtitude'
18
20
  confirm:
19
21
  destroy:
20
22
  header: 'You are going to delete following record:'
@@ -15,6 +15,8 @@ ru:
15
15
  filters: 'Фильтры'
16
16
  details: 'Подробная информация'
17
17
  destroying: 'Удаление'
18
+ latitude: 'Широта'
19
+ longtitude: 'Долгота'
18
20
  confirm:
19
21
  destroy:
20
22
  header: 'Вы собираетесь удалить следующую запись:'
@@ -1,5 +1,5 @@
1
1
  #
2
2
  module AdminIt
3
3
  # Current gem version
4
- VERSION = '1.2.5'
4
+ VERSION = '1.2.6'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: admin_it
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.5
4
+ version: 1.2.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexey Ovchinnikov
@@ -252,6 +252,7 @@ files:
252
252
  - app/assets/javascript/admin_it/jquery.fileupload-process.js
253
253
  - app/assets/javascript/admin_it/jquery.fileupload-ui.js
254
254
  - app/assets/javascript/admin_it/jquery.fileupload.js
255
+ - app/assets/javascript/admin_it/jquery.geolocationpicker.js
255
256
  - app/assets/javascript/admin_it/jquery.ui.widget.js
256
257
  - app/assets/stylesheets/admin_it/admin_it.css
257
258
  - app/assets/stylesheets/admin_it/bootstrap-theme.min.css
@@ -267,6 +268,7 @@ files:
267
268
  - app/views/admin_it/context/_tiles.html.slim
268
269
  - app/views/admin_it/edit.html.slim
269
270
  - app/views/admin_it/editors/_combo.html.slim
271
+ - app/views/admin_it/editors/_geo_picker.html.slim
270
272
  - app/views/admin_it/editors/_hidden.html.slim
271
273
  - app/views/admin_it/editors/_image.html.slim
272
274
  - app/views/admin_it/editors/_text.html.slim