@retailcrm/embed-ui-v1-endpoint 0.9.26 → 0.9.28

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.
@@ -168,9 +168,12 @@ When working with \`${PACKAGE_NAME}\` in this project:
168
168
  7. Then read the relevant \`embed-ui-v1-endpoint://targets/<encoded-target>\` resource before answering or changing code related to that target.
169
169
  8. For widget UI composition, keep inline target content compact: prefer \`UiToolbarButton\`, \`UiToolbarLink\`, short text, and icons; move complex UI into \`UiModalSidebar\` or \`UiModalWindow\`.
170
170
  9. If \`@retailcrm/embed-ui-v1-components\` is installed, read its widget composition docs before building widget UI.
171
- 10. A project \`.mcp.json\` may require restarting or reconnecting the AI client before MCP resources appear in the current session.
172
- 11. If MCP resources are not available, use the generated YAML profiles from \`./node_modules/${PACKAGE_NAME}/docs/targets/*.yml\` as the fallback source.
173
- 12. Prefer target profiles over guessing target placement, contexts, or semantic intent from names alone.
171
+ 10. Before choosing RetailCRM system \`menu\` or \`parentMenuItemCode\`, read \`https://docs.retailcrm.ru/api/ru/RetailCRM/jsApiMethods/navigation\`; do not guess menu codes from section names or stale examples.
172
+ 11. A project \`.mcp.json\` may require restarting or reconnecting the AI client before MCP resources appear in the current session.
173
+ 12. If MCP resources are not available, use the generated YAML profiles from \`./node_modules/${PACKAGE_NAME}/docs/targets/*.yml\` as the fallback source.
174
+ 13. Prefer target profiles over guessing target placement, contexts, or semantic intent from names alone.
175
+ 14. Keep page switch/root components thin; move shared locale synchronization and context plumbing into composables or plugins when several embed pages need them.
176
+ 15. Prefer domain-specific frontend API helpers over one generic page-level transport helper, and preserve structured API errors.
174
177
 
175
178
  Suggested MCP stdio server configuration:
176
179
 
@@ -61,6 +61,26 @@ const pageRunner = definePageRunner({
61
61
  Если ошибка видна только в minified bundle, соберите или отдайте dev bundle без минификации до изменения кода
62
62
  по догадке.
63
63
 
64
+ ## Shared page setup
65
+
66
+ Если runner обслуживает несколько embed pages, держите root/switch component максимально тонким: он выбирает
67
+ компонент страницы по `code`, но не должен дублировать context plumbing, синхронизацию локали и API-адаптеры
68
+ каждой страницы.
69
+
70
+ Для i18n используйте общий composable или plugin, который синхронизирует remote locale из settings/context
71
+ источника, принятого в проекте. Если локаль нужна нескольким embed pages, не копируйте один и тот же watch/load
72
+ код в каждую страницу и не прячьте его в page switch без явной причины.
73
+
74
+ Для admin pages с несколькими сущностями предпочитайте тонкие domain helpers вместо одного безымянного
75
+ `callAdminApi`: `loadSettings`, `saveSettings`, `loadSpecialties`, `saveSpecialist`, `deleteSpecialist` и т.п.
76
+ Такие helpers должны сохранять transport details внутри integration layer, но отражать доменный контракт страницы
77
+ в именах и типах.
78
+
79
+ Ошибки API сохраняйте структурированными: status, field errors, error codes и machine-readable детали не должны
80
+ теряться при преобразовании в UI state. Если API возвращает error codes, frontend может переводить их в локали UI;
81
+ готовый backend message допустим как fallback или специальное продуктовое требование, но не должен быть
82
+ единственным typed contract для сложной формы.
83
+
64
84
  ## `beforeMount`
65
85
 
66
86
  `beforeMount` вызывается после `app.use(pinia)` и до `app.mount(...)`.
@@ -16,6 +16,19 @@
16
16
  `menu item` не равен `target`. Меню открывает полноценную встраиваемую страницу по `code`, а `target`
17
17
  используется для виджетов, которые встраиваются внутрь уже существующей CRM-страницы.
18
18
 
19
+ ## Справочник системных меню RetailCRM
20
+
21
+ Коды системных меню и родительских пунктов меню RetailCRM обязательно сверяйте с актуальным
22
+ JSON-справочником:
23
+
24
+ https://docs.retailcrm.ru/api/ru/RetailCRM/jsApiMethods/navigation
25
+
26
+ Этот ресурс отдаёт фактические `menus[]` и `menu_items[]`, которые использует документация RetailCRM.
27
+ Не подбирайте `menu` и `parentMenuItemCode` по названию раздела или по старым примерам: перед добавлением
28
+ или изменением страницы перечитайте справочник и выберите код из него. Например, для страницы в настройках
29
+ валидная пара обычно выглядит как `menu: "private_main_menu"` и `parentMenuItemCode: "settings"`, а для
30
+ страницы в продажах — `menu: "activity_main_menu"` и подходящий пункт из `menu_items[]` этого меню.
31
+
19
32
  ## Что фиксировать в справочнике проекта
20
33
 
21
34
  Для каждого пункта меню указывайте:
@@ -59,7 +72,7 @@
59
72
  `menu` обязателен для опубликованной страницы: без него backend не сможет открыть route вида
60
73
  `/modules/<module-code>/<page-code>`. Для страниц в разделе настроек обычно используется
61
74
  `menu: "private_main_menu"` и `parentMenuItemCode: "settings"`. Для страниц в разделе продаж используйте
62
- `menu: "activity_main_menu"` и соответствующий parent menu item, например `orders`.
75
+ `menu: "activity_main_menu"` и соответствующий parent menu item из справочника RetailCRM.
63
76
 
64
77
  CRM также использует hierarchy из `pages[]` для видимой навигации и breadcrumb-like поведения. Сначала
65
78
  моделируйте нужную иерархию через `menu`, `parentMenuItemCode` и `menuItemOrdering`; локальные ссылки внутри
@@ -105,7 +118,9 @@ method с обычным JSON-объектом вместо добавления
105
118
 
106
119
  ## Пример справочника меню
107
120
 
108
- Конкретные `placement`, `item code` и `route` нужно брать из host/manifest расширения.
121
+ Конкретные локальные `placement`, `item code` и `route` нужно брать из host/manifest расширения. Системные
122
+ `menu` и `parentMenuItemCode` для RetailCRM сначала сверяйте со справочником
123
+ `https://docs.retailcrm.ru/api/ru/RetailCRM/jsApiMethods/navigation`.
109
124
 
110
125
  | Placement | Item code | Label | Page code | Route | Когда использовать |
111
126
  | --- | --- | --- | --- | --- | --- |
@@ -98,6 +98,26 @@ const openSettings = (host: HostApi) => {
98
98
  }
99
99
  ```
100
100
 
101
+ ## Уведомление перед уходом со страницы
102
+
103
+ Если странице нужно сообщить host, что уход с текущего URL нежелателен, зарегистрируйте
104
+ `HostApi.onBeforeRouteLeave(hook)`.
105
+
106
+ ```ts
107
+ import type { HostApi } from '@retailcrm/embed-ui-v1-types/host'
108
+
109
+ const registerLeaveGuard = (host: HostApi, hasUnsavedChanges: () => boolean) => {
110
+ host.onBeforeRouteLeave(() => !hasUnsavedChanges())
111
+ }
112
+ ```
113
+
114
+ `true` означает, что расширение подтверждает возможность перехода. `false` означает, что расширение
115
+ не подтверждает переход, например потому что пользователь может потерять несохраненные изменения.
116
+ Это не жесткая блокировка навигации со стороны расширения: host может учесть результат, показать
117
+ диалог подтверждения, остаться на текущем URL или проигнорировать мнение расширения, если так устроен
118
+ конкретный сценарий. Метод нужен как общий способ уведомить host о состоянии страницы перед сменой
119
+ маршрута.
120
+
101
121
  Breadcrumb-like navigation для module pages строится CRM из hierarchy в `pages[]`: `menu`,
102
122
  `parentMenuItemCode`, `menuItemOrdering` и связанных metadata. Не собирайте breadcrumbs вручную внутри
103
123
  страницы, если продуктовая задача явно не просит локальную in-page navigation.
@@ -107,4 +127,5 @@ Breadcrumb-like navigation для module pages строится CRM из hierarc
107
127
  - [`menu-placements`](./menu-placements.md) — как связать пункт меню, page `code` и маршрут.
108
128
  - [`definePageRunner`](./define-page-runner.md) — как page `code` попадает в компонент.
109
129
  - `@retailcrm/embed-ui-v1-contexts` `docs/ru/CONCEPT.md` — общий принцип работы контекстов.
110
- - `@retailcrm/embed-ui-v1-types` `host.d.ts` — публичный тип host API с `goTo`.
130
+ - `@retailcrm/embed-ui-v1-types` `host.d.ts` — публичный тип host API с `goTo` и
131
+ `onBeforeRouteLeave`.
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "embed-ui-v1-endpoint-mcp": "bin/embed-ui-v1-endpoint-mcp.mjs"
6
6
  },
7
7
  "type": "module",
8
- "version": "0.9.26",
8
+ "version": "0.9.28",
9
9
  "description": "Endpoint API for integrations in RetailCRM",
10
10
  "license": "MIT",
11
11
  "author": "RetailDriverLLC <integration@retailcrm.ru>",
@@ -101,28 +101,28 @@
101
101
  "peerDependencies": {
102
102
  "@omnicajs/vue-remote": "^0.2.24",
103
103
  "@remote-ui/rpc": "^1.4",
104
- "@retailcrm/embed-ui-v1-contexts": "^0.9.26",
105
- "@retailcrm/embed-ui-v1-types": "^0.9.26",
104
+ "@retailcrm/embed-ui-v1-contexts": "^0.9.28",
105
+ "@retailcrm/embed-ui-v1-types": "^0.9.28",
106
106
  "pinia": "^2.2",
107
107
  "vue": "^3.5"
108
108
  },
109
109
  "dependencies": {
110
110
  "@modelcontextprotocol/sdk": "^1.29.0",
111
111
  "@remote-ui/rpc": "^1.4.7",
112
- "@retailcrm/embed-ui-v1-components": "^0.9.26",
113
- "@retailcrm/embed-ui-v1-contexts": "^0.9.26",
114
- "@retailcrm/embed-ui-v1-types": "^0.9.26"
112
+ "@retailcrm/embed-ui-v1-components": "^0.9.28",
113
+ "@retailcrm/embed-ui-v1-contexts": "^0.9.28",
114
+ "@retailcrm/embed-ui-v1-types": "^0.9.28"
115
115
  },
116
116
  "devDependencies": {
117
117
  "@retailcrm/image-preview": "^1.0.2",
118
- "@vitest/browser": "4.1.3",
119
- "@vitest/browser-playwright": "4.1.3",
118
+ "@vitest/browser": "4.1.8",
119
+ "@vitest/browser-playwright": "4.1.8",
120
120
  "date-fns": "^4.1.0",
121
121
  "playwright": "1.58.2",
122
122
  "tsx": "^4.21.0",
123
123
  "vite": "^7.3.2",
124
124
  "vite-plugin-dts": "^4.5.4",
125
- "vitest": "4.1.3"
125
+ "vitest": "4.1.8"
126
126
  },
127
127
  "publishConfig": {
128
128
  "access": "public"
@@ -30,12 +30,15 @@ Use this skill before changing JS module endpoint wiring, page registration, wid
30
30
  4. Use documented public entrypoints such as `@retailcrm/embed-ui-v1-endpoint/remote`; do not import from `dist/*`, source files, or repository-only paths.
31
31
  5. Keep widget inline UI compact; use component package widget composition guidance for UI mounted into CRM targets.
32
32
  6. After the first page vertical slice, verify it in the CRM host: menu item, `/modules/<moduleCode>/<pageCode>` route, entrypoint URL, stylesheet URL, and actual frontend mount.
33
- 7. If a runtime error appears only in a minified bundle, switch to a dev bundle or sourcemaps before guessing.
33
+ 7. Keep page switch/root components thin; move shared locale synchronization and context plumbing into composables or plugins when several embed pages need them.
34
+ 8. Prefer domain-specific frontend API helpers over one generic page-level `callAdminApi`; preserve status, field errors, and error codes in structured error objects.
35
+ 9. If a runtime error appears only in a minified bundle, switch to a dev bundle or sourcemaps before guessing.
34
36
 
35
37
  ## Page and menu checks
36
38
 
37
39
  - Published page descriptors must be objects, not string page codes.
38
40
  - Page descriptors need `code`, `menu`, and usually `menuItemTitle`.
41
+ - Before choosing RetailCRM system `menu` or `parentMenuItemCode`, read `https://docs.retailcrm.ru/api/ru/RetailCRM/jsApiMethods/navigation`; do not guess menu codes from section names or stale examples.
39
42
  - Use `parentMenuItemCode` and `menuItemOrdering` to model the intended CRM page/menu hierarchy.
40
43
  - Breadcrumb-like navigation is derived by CRM from the page/menu hierarchy passed in the extension config; do not hand-roll breadcrumbs in the page unless the product task explicitly asks for local in-page navigation.
41
44
  - For updating an already installed module, use the existing integration module edit/update flow and put pages under `integrationModule.integrations.embedJs.pages`.
@@ -46,3 +49,10 @@ Use this skill before changing JS module endpoint wiring, page registration, wid
46
49
  - Use public Host API for location, query state, and navigation.
47
50
  - Do not depend on internal endpoint runtime stores or private channel state.
48
51
  - Keep route names, page codes, and extension descriptor values documented in the project.
52
+
53
+ ## Shared page setup checks
54
+
55
+ - If i18n is used by several embed pages, synchronize remote locale once through a shared composable or plugin.
56
+ - Do not duplicate the same locale watch/load code in every page component.
57
+ - Domain helpers such as `loadSettings`, `saveSettings`, `loadSpecialties`, `saveSpecialist`, and `deleteSpecialist` should express page contracts better than generic transport calls.
58
+ - If the API returns machine-readable error codes, translate them in the frontend UI layer; backend messages may be fallbacks or explicit product requirements, not the only structured contract.