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 +4 -4
- data/CHANGELOG.md +41 -0
- data/README.md +3 -1
- data/app/helpers/cdek/widget_helper.rb +4 -1
- data/lib/cdek/version.rb +1 -1
- data/lib/generators/cdek/install/templates/cdek_widget_controller.js +13 -19
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1dd8710b9122c71addd999aab3d16759f3a919916a11e3d1715d88483d6aa21b
|
|
4
|
+
data.tar.gz: 50b97380e716f8b23c4d75165552caff3c93856b814a3f64b2ac725e6a61ff02
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
@@ -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
|
|
50
|
-
|
|
51
|
-
|
|
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 = () =>
|
|
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
|
-
|
|
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)
|