cdek 0.3.14 → 0.3.16

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
  SHA256:
3
- metadata.gz: 876ccf8ab0ab45c5d2ea73d3a2abd8d396e5abcedf8c30d7fbdd3c18fbaf9f00
4
- data.tar.gz: af5b8ea84efcfd064cf7a265405ecc5d0460bb338ec12f4fc25d3c4ac2e885e1
3
+ metadata.gz: 1dd8710b9122c71addd999aab3d16759f3a919916a11e3d1715d88483d6aa21b
4
+ data.tar.gz: 50b97380e716f8b23c4d75165552caff3c93856b814a3f64b2ac725e6a61ff02
5
5
  SHA512:
6
- metadata.gz: 6da66c243aeba6ee2c00c6f151b1873c9b5c47924eb89cf5f9a6031d9edc002d04320a7f71b419fcad64190c25c3968efcf1161538f228798a8953c360bf4502
7
- data.tar.gz: d49a1accd14e41e2b4cf199e3f6a42892a61a32400e3f683519b12aa81a0b51d1d84ef47489bd35b47261aa3fc30c3da75df2e885604c436125d14e7f9f552ce
6
+ metadata.gz: b4adea92e439961fce478880f1792bb9790809bdf1073e3bc1ba45a4468652558f59278bae279bd0bf40643876bcf9ea96e14f9c6c7e4f779d150baa299b444b
7
+ data.tar.gz: be21d7a9b78b4bdefc1c624742b6a52e5de70228b93497571731ff714379f936f035792fa5dad2daa7963096195eab58e7bcdb86a54add254df46f24e3dde87d
data/CHANGELOG.md CHANGED
@@ -1,5 +1,46 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.16
4
+
5
+ * Полная изоляция инстансов виджета между открытиями карты. Singleton-гард
6
+ 0.3.14 (один живой инстанс) оказался недостаточным: `@cdek-it/widget@3`
7
+ держит ГЛОБАЛЬНЫЙ pinia-стор на уровне модуля, а `destroy()` размонтирует
8
+ Vue-приложение, но не очищает этот стор и не снимает подписки, заведённые
9
+ в бутстрапе виджета (вне дерева компонентов). После смены города
10
+ (пересоздания модалки) подписки уничтоженного инстанса оставались на общем
11
+ сторе и, реагируя на запись нового инстанса, перезапрашивали офисы и
12
+ пере-центрировали карту на ПРЕЖНИЙ город — точки нового города уходили
13
+ «за границы» и пропадали навсегда (в server-логах — `widget_service` по
14
+ старому городу сразу после нового).
15
+ * Решение: шаблон `cdek_widget_controller.js` теперь перед каждым монтажом
16
+ удаляет `window.CDEKWidget` и заново выполняет бандл, поэтому каждый виджет
17
+ получает свежий модуль со своим стором, а подписки прежнего инстанса висят
18
+ на осиротевшем сторе и на новый виджет не влияют. Повторное выполнение
19
+ бандла безопасно: Yandex Maps (ymaps3) грузится идемпотентно, дублирование
20
+ `<style>` безвредно, custom elements не регистрируются. Прежний
21
+ `ensureWidgetScript` (один общий `_scriptPromise`) заменён на
22
+ `loadFreshWidgetScript`.
23
+ * Шаблон генератора снова пишет координаты выбранного ПВЗ (`office.location`
24
+ → строка `"lon lat"`) в скрытое поле `order_cdek_point_coors`. Поддержка
25
+ `fieldCoors` была в host-копиях ≤0.3.12, но потерялась при переносе фиксов
26
+ 0.3.13/0.3.14 в шаблон — из-за этого после синхронизации контроллера
27
+ хост-приложение переставало получать координаты пункта и не могло
28
+ отрисовать карту заказа. Значение `fieldCoors` (по умолчанию
29
+ `order_cdek_point_coors`) и его data-атрибут `cdek_widget_field_coors_value`
30
+ добавлены и в шаблон, и в `cdek_widget_tag` (новый необязательный параметр
31
+ `field_coors:`), консистентно с остальными `field_*`.
32
+ * Шаблон: после асинхронной загрузки скрипта виджета монтирование
33
+ выполняется только если контроллер ещё подключён
34
+ (`if (this._connected) this._mountWidget()`). Раньше промис загрузки мог
35
+ доехать уже после `disconnect()` (быстрое закрытие/переоткрытие модалки),
36
+ и виджет монтировался в уже отсоединённый узел.
37
+ * Совокупно с 0.3.13 (центрирование карты по координатам вместо асинхронного
38
+ геокодинга названия) и 0.3.14 (ровно один живой инстанс) это полностью
39
+ убирает «мелькание» и пропадание точек ПВЗ при открытии карты после смены
40
+ города. Хост-приложениям, сгенерировавшим контроллер на ≤0.3.15, нужно
41
+ перегенерировать его (`bin/rails generate cdek:install`) или внести правку
42
+ вручную из шаблона.
43
+
3
44
  ## 0.3.14
4
45
 
5
46
  * Шаблон генератора `cdek_widget_controller.js` теперь держит ровно один
data/README.md CHANGED
@@ -115,9 +115,11 @@ suggestions = Cdek.city_suggestions("мос")
115
115
  * `#order_cdek_point_name`
116
116
  * `#order_cdek_point_address`
117
117
  * `#order_cdek_city_code`
118
+ * `#order_cdek_point_coors` — координаты ПВЗ строкой `"долгота широта"`
119
+ (из `office.location`), чтобы хост мог отрисовать карту заказа.
118
120
 
119
121
  DOM-id переопределяются именованными аргументами `field_code`,
120
- `field_name`, `field_address`, `field_city_code` хелпера.
122
+ `field_name`, `field_address`, `field_city_code`, `field_coors` хелпера.
121
123
 
122
124
  5. Также диспатчится событие `cdek-widget:chosen` с `detail.office` —
123
125
  можно слушать в собственных Stimulus-контроллерах.
@@ -43,6 +43,7 @@ module Cdek
43
43
  field_name: "order_cdek_point_name",
44
44
  field_address: "order_cdek_point_address",
45
45
  field_city_code: "order_cdek_city_code",
46
+ field_coors: "order_cdek_point_coors",
46
47
  label_selector: "[data-cdek-widget-label]",
47
48
  address_selector: "#order_cdek_point_address_view",
48
49
  height: "600px")
@@ -62,6 +63,7 @@ module Cdek
62
63
  field_name: field_name,
63
64
  field_address: field_address,
64
65
  field_city_code: field_city_code,
66
+ field_coors: field_coors,
65
67
  label_selector: label_selector,
66
68
  address_selector: address_selector
67
69
  )
@@ -95,7 +97,7 @@ module Cdek
95
97
  def cdek_widget_data(api_key:, default_city:, default_coords:, sender_city:, sender_city_code:,
96
98
  goods_json:,
97
99
  service_path:, script_url:, modal_id:,
98
- field_code:, field_name:, field_address:, field_city_code:,
100
+ field_code:, field_name:, field_address:, field_city_code:, field_coors:,
99
101
  label_selector:, address_selector:)
100
102
  {
101
103
  controller: "cdek-widget",
@@ -112,6 +114,7 @@ module Cdek
112
114
  cdek_widget_field_name_value: field_name,
113
115
  cdek_widget_field_address_value: field_address,
114
116
  cdek_widget_field_city_code_value: field_city_code,
117
+ cdek_widget_field_coors_value: field_coors,
115
118
  cdek_widget_label_selector_value: label_selector,
116
119
  cdek_widget_address_selector_value: address_selector
117
120
  }
data/lib/cdek/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Cdek
4
- VERSION = "0.3.14"
4
+ VERSION = "0.3.16"
5
5
  end
@@ -26,15 +26,6 @@ import { Controller } from "@hotwired/stimulus"
26
26
  // виджет будет открыт без расчётных packages, чтобы не считать доставку
27
27
  // по выдуманным размерам.
28
28
 
29
- let _scriptPromise = null
30
-
31
- // @cdek-it/widget@3 — Vue-приложение с ГЛОБАЛЬНЫМ стором (singleton). Два
32
- // живых инстанса делят один стор и конфликтуют: монтаж нового перенастраивает
33
- // общий стор, и старый перезапрашивает офисы и пере-центрирует карту на
34
- // прежний город (в server-логах — повторные widget_service по старому городу
35
- // сразу после нового). Поэтому держим ровно один живой виджет на странице и
36
- // гасим предыдущий ПЕРЕД монтажом нового. destroy() у виджета бросает, если он
37
- // ещё не домонтировался, — глушим, ссылку всё равно чистим.
38
29
  let _activeWidget = null
39
30
 
40
31
  function destroyWidget(widget) {
@@ -46,20 +37,16 @@ function destroyWidget(widget) {
46
37
  if (_activeWidget === widget) _activeWidget = null
47
38
  }
48
39
 
49
- function ensureWidgetScript(url) {
50
- if (typeof window.CDEKWidget !== "undefined") {
51
- return Promise.resolve()
52
- }
53
- if (_scriptPromise) return _scriptPromise
54
- _scriptPromise = new Promise((resolve, reject) => {
40
+ function loadFreshWidgetScript(url) {
41
+ return new Promise((resolve, reject) => {
42
+ try { delete window.CDEKWidget } catch (_) { window.CDEKWidget = undefined }
55
43
  const s = document.createElement("script")
56
44
  s.src = url
57
45
  s.async = true
58
46
  s.onload = () => resolve()
59
- s.onerror = () => { _scriptPromise = null; reject(new Error("Не удалось загрузить скрипт виджета СДЭК")) }
47
+ s.onerror = () => reject(new Error("Не удалось загрузить скрипт виджета СДЭК"))
60
48
  document.head.appendChild(s)
61
49
  })
62
- return _scriptPromise
63
50
  }
64
51
 
65
52
  function setFieldValue(id, value) {
@@ -104,6 +91,7 @@ export default class extends Controller {
104
91
  fieldName: { type: String, default: "order_cdek_point_name" },
105
92
  fieldAddress: { type: String, default: "order_cdek_point_address" },
106
93
  fieldCityCode: { type: String, default: "order_cdek_city_code" },
94
+ fieldCoors: { type: String, default: "order_cdek_point_coors" },
107
95
  labelSelector: { type: String, default: "[data-cdek-widget-label]" },
108
96
  addressSelector: { type: String, default: "#order_cdek_point_address_view" }
109
97
  }
@@ -131,8 +119,8 @@ export default class extends Controller {
131
119
  }
132
120
 
133
121
  this._mounting = true
134
- ensureWidgetScript(this.scriptUrlValue)
135
- .then(() => this._mountWidget())
122
+ loadFreshWidgetScript(this.scriptUrlValue)
123
+ .then(() => { if (this._connected) this._mountWidget() })
136
124
  .catch((err) => this._showError(err && err.message ? err.message : "ошибка"))
137
125
  .finally(() => { this._mounting = false })
138
126
  }
@@ -225,10 +213,16 @@ export default class extends Controller {
225
213
  const address = office.address || office.address_full || ""
226
214
  const cityCode = office.city_code || ""
227
215
 
216
+ const loc = Array.isArray(office.location) ? office.location : []
217
+ const lon = Number(loc[0])
218
+ const lat = Number(loc[1])
219
+ const coors = (Number.isFinite(lon) && Number.isFinite(lat)) ? `${lon} ${lat}` : ""
220
+
228
221
  setFieldValue(this.fieldCodeValue, code)
229
222
  setFieldValue(this.fieldNameValue, name)
230
223
  setFieldValue(this.fieldAddressValue, address)
231
224
  setFieldValue(this.fieldCityCodeValue, cityCode)
225
+ setFieldValue(this.fieldCoorsValue, coors)
232
226
 
233
227
  const label = name ? (code ? `${name} (${code})` : name) : "не выбран"
234
228
  setText(this.labelSelectorValue, label)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cdek
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.14
4
+ version: 0.3.16
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sergey Korolyov