wenay-react2 1.0.49 → 1.0.51

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.
Files changed (54) hide show
  1. package/README.md +14 -14
  2. package/doc/EXAMPLE_USAGE.md +48 -0
  3. package/doc/PROJECT_FUNCTIONALITY.md +13 -2
  4. package/doc/PROJECT_RULES.md +27 -27
  5. package/doc/WENAY_REACT2_RENAMES.md +170 -170
  6. package/doc/changes/v1.0.41.md +35 -35
  7. package/doc/changes/v1.0.42.md +26 -26
  8. package/doc/changes/v1.0.43.md +10 -10
  9. package/doc/changes/v1.0.44.md +14 -14
  10. package/doc/changes/v1.0.45.md +8 -8
  11. package/doc/changes/v1.0.46.md +11 -11
  12. package/doc/changes/v1.0.47.md +9 -9
  13. package/doc/changes/v1.0.48.md +8 -8
  14. package/doc/changes/v1.0.49.md +7 -7
  15. package/doc/changes/v1.0.50.md +7 -0
  16. package/doc/changes/v1.0.51.md +10 -0
  17. package/doc/examples/README.md +1 -1
  18. package/doc/examples/conference-client.html +34 -34
  19. package/doc/examples/conference-client.ts +212 -212
  20. package/doc/examples/conference-server.mjs +150 -150
  21. package/doc/examples/peer-call-media.tsx +7 -7
  22. package/doc/examples/stand.tsx +5 -5
  23. package/doc/native.md +37 -37
  24. package/doc/progress/README.md +13 -13
  25. package/doc/progress/architecture-fix-queue.md +74 -74
  26. package/doc/progress/column-state-present-gate.md +28 -28
  27. package/doc/progress/common2-adoption-1.0.73.md +28 -28
  28. package/doc/progress/common2-adoption-1.0.74.md +24 -24
  29. package/doc/progress/common2-adoption-1.0.75.md +120 -0
  30. package/doc/progress/hook-controller-opportunities.md +363 -363
  31. package/doc/progress/hook-extraction-audit.md +195 -195
  32. package/doc/progress/public-surface-normalization.md +351 -351
  33. package/doc/progress/qa-stand-walkthrough-2026-07-12.md +62 -62
  34. package/doc/progress/stand-as-examples-audit.md +20 -20
  35. package/doc/progress/style-system-normalization.md +121 -121
  36. package/doc/target/README.md +32 -32
  37. package/doc/target/my.md +11 -3
  38. package/doc/wenay-react2-rare.md +11 -7
  39. package/doc/wenay-react2.md +2 -2
  40. package/lib/common/src/grid/agGrid4/core.js +7 -2
  41. package/lib/common/src/hooks/useReplay.js +13 -2
  42. package/lib/common/src/logs/logs.d.ts +4 -1
  43. package/lib/common/src/logs/logs.js +19 -11
  44. package/lib/common/testUseReact/replayVideo.d.ts +5 -0
  45. package/lib/common/testUseReact/replayVideo.js +98 -1
  46. package/lib/style/menuRight.css +19 -19
  47. package/lib/style/style.css +23 -23
  48. package/lib/style/tokens.css +184 -184
  49. package/package.json +54 -54
  50. package/doc/changes/v1.0.35.md +0 -26
  51. package/doc/changes/v1.0.37.md +0 -13
  52. package/doc/changes/v1.0.38.md +0 -48
  53. package/doc/changes/v1.0.39.md +0 -35
  54. package/doc/changes/v1.0.40.md +0 -15
@@ -1,368 +1,368 @@
1
- # Public surface normalization
2
-
3
- Задача из target: пройти второй слой публичной поверхности `wenay-react2` и внедрять только те primitives, которые реально заменяют ручной код.
4
-
5
- ## Status
6
-
7
- In progress.
8
-
9
- ## Usage/example sources
10
-
11
- Обновляем вместе с кодом, если меняется canonical usage:
12
- - `doc/EXAMPLE_USAGE.md` — главный standards/example файл;
13
- - `src/common/testUseReact/qa.tsx` — QA cards как живые примеры использования, особенно cards 20-31;
14
- - `src/common/testUseReact/replayVideo.tsx` — Replay usage examples для cards 23-26;
15
- - `src/common/src/grid/agGrid4/example.tsx`, `README.md`, `WRAPPER.md`, `MIGRATION.md` — grid wrapper examples/docs.
16
-
17
- Legacy/compat examples (`src/common/testUseReact/use.tsx`, `useGrid.tsx`, отдельные старые cards) не переписывать автоматически; если они показывают low-level path, помечать как regression/compat, а не canonical pattern.
18
-
19
- Правило прохода: для каждого изменения проверять, есть ли affected card/example. Если публичный API не менялся и пример уже показывает правильный usage, фиксировать "пример проверен, менять не нужно".
20
-
21
- ## Task scoring
22
-
23
- Перед выполнением следующего кандидата ставим оценку:
24
- - эффективность: high / medium / low;
25
- - простота: simple / medium / hard;
26
- - риск: low / medium / high.
27
-
28
- Делаем сразу только high/medium эффективность при simple/medium сложности и понятном риске. Low-effectiveness или hard/high-risk без явного выигрыша — пропускать и записывать причину.
29
-
30
- ## Pass 1 — low-risk controller reuse
31
-
32
- ### `createUpdateApi` / `useUpdateByApi`
33
-
34
- Проверено:
35
- - `src/common/src/hooks/useKeyboard.ts` содержит простой mutable singleton `keyboardState` и прямые вызовы `renderBy(keyboardState)`.
36
-
37
- Сделано:
38
- - `useKeyboard.ts` переведён на `createUpdateApi(keyboardState)` для локального render-controller.
39
- - Публичный API `keyboard`, `keyboardState`, `useKeyboard`, `keyboard.on/subscribe` не менялся.
40
-
41
- Почему это не высосано из пальца:
42
- - это ровно contract `createUpdateApi`: mutable object + render/subscribe controller;
43
- - изменение маленькое и не тянет UI-поведение.
44
-
45
- Ограничение:
46
- - широкая замена `updateBy/renderBy` в `Toolbar`, `SettingsDialog`, `columnState` пока не делалась. Там controller может быть полезен, но риск выше, потому что эти объекты имеют persistence, registry или grid side effects.
47
-
48
- ## Pass 1 — tasks intentionally not implemented yet
49
-
50
- ### `ArrayPromise`
51
-
52
- Статус: пока не внедрять.
53
-
54
- Причина:
55
- - в текущей библиотеке нет потребителя, где явно нужен именно последовательный набор promise-thunks с progress counters;
56
- - для параллельных batch operations counters у `ArrayPromise` не являются стабильным контрактом;
57
- - внедрение без конкретной batch-команды будет искусственным.
58
-
59
- Что считать подходящим местом позже:
60
- - реальные последовательные операции: массовое закрытие позиций, очистка лимиток, transfer step-by-step;
61
- - если операции параллельные, нужен другой progress contract, не `ArrayPromise` counters.
62
-
63
- ### `DragBox` / `DragArea`
64
-
65
- Статус: не использовать в новом коде как high-level стандарт.
66
-
67
- Причина:
68
- - это low-level/legacy movement components;
69
- - для нового кода уже есть hook-first путь `useDraggableApi`, а для окон — `FloatingWindow`.
70
-
71
-
72
- ## Pass 2 — grid helpers without grid lifecycle change
73
-
74
- ### Log tables default column definition
75
-
76
- Проверено:
77
- - `src/common/src/logs/miniLogs.tsx` и `src/common/src/logs/logs.tsx` дублировали один и тот же `defaultColDef`: `headerClass`, `resizable`, centered `cellStyle`, `sortable`, `filter`, `wrapText`.
78
-
79
- Сделано:
80
- - оба места переведены на общий `colDefCentered` + локальный `wrapText: true`.
81
- - `AgGridReact` намеренно оставлен на месте: перевод на `AgGridTable` может изменить тему, row selection и lifecycle, поэтому это отдельная задача после визуальной проверки.
82
-
83
- Почему это не высосано из пальца:
84
- - helper `colDefCentered` уже существует именно для такого dense table default;
1
+ # Public surface normalization
2
+
3
+ Задача из target: пройти второй слой публичной поверхности `wenay-react2` и внедрять только те primitives, которые реально заменяют ручной код.
4
+
5
+ ## Status
6
+
7
+ In progress.
8
+
9
+ ## Usage/example sources
10
+
11
+ Обновляем вместе с кодом, если меняется canonical usage:
12
+ - `doc/EXAMPLE_USAGE.md` — главный standards/example файл;
13
+ - `src/common/testUseReact/qa.tsx` — QA cards как живые примеры использования, особенно cards 20-31;
14
+ - `src/common/testUseReact/replayVideo.tsx` — Replay usage examples для cards 23-26;
15
+ - `src/common/src/grid/agGrid4/example.tsx`, `README.md`, `WRAPPER.md`, `MIGRATION.md` — grid wrapper examples/docs.
16
+
17
+ Legacy/compat examples (`src/common/testUseReact/use.tsx`, `useGrid.tsx`, отдельные старые cards) не переписывать автоматически; если они показывают low-level path, помечать как regression/compat, а не canonical pattern.
18
+
19
+ Правило прохода: для каждого изменения проверять, есть ли affected card/example. Если публичный API не менялся и пример уже показывает правильный usage, фиксировать "пример проверен, менять не нужно".
20
+
21
+ ## Task scoring
22
+
23
+ Перед выполнением следующего кандидата ставим оценку:
24
+ - эффективность: high / medium / low;
25
+ - простота: simple / medium / hard;
26
+ - риск: low / medium / high.
27
+
28
+ Делаем сразу только high/medium эффективность при simple/medium сложности и понятном риске. Low-effectiveness или hard/high-risk без явного выигрыша — пропускать и записывать причину.
29
+
30
+ ## Pass 1 — low-risk controller reuse
31
+
32
+ ### `createUpdateApi` / `useUpdateByApi`
33
+
34
+ Проверено:
35
+ - `src/common/src/hooks/useKeyboard.ts` содержит простой mutable singleton `keyboardState` и прямые вызовы `renderBy(keyboardState)`.
36
+
37
+ Сделано:
38
+ - `useKeyboard.ts` переведён на `createUpdateApi(keyboardState)` для локального render-controller.
39
+ - Публичный API `keyboard`, `keyboardState`, `useKeyboard`, `keyboard.on/subscribe` не менялся.
40
+
41
+ Почему это не высосано из пальца:
42
+ - это ровно contract `createUpdateApi`: mutable object + render/subscribe controller;
43
+ - изменение маленькое и не тянет UI-поведение.
44
+
45
+ Ограничение:
46
+ - широкая замена `updateBy/renderBy` в `Toolbar`, `SettingsDialog`, `columnState` пока не делалась. Там controller может быть полезен, но риск выше, потому что эти объекты имеют persistence, registry или grid side effects.
47
+
48
+ ## Pass 1 — tasks intentionally not implemented yet
49
+
50
+ ### `ArrayPromise`
51
+
52
+ Статус: пока не внедрять.
53
+
54
+ Причина:
55
+ - в текущей библиотеке нет потребителя, где явно нужен именно последовательный набор promise-thunks с progress counters;
56
+ - для параллельных batch operations counters у `ArrayPromise` не являются стабильным контрактом;
57
+ - внедрение без конкретной batch-команды будет искусственным.
58
+
59
+ Что считать подходящим местом позже:
60
+ - реальные последовательные операции: массовое закрытие позиций, очистка лимиток, transfer step-by-step;
61
+ - если операции параллельные, нужен другой progress contract, не `ArrayPromise` counters.
62
+
63
+ ### `DragBox` / `DragArea`
64
+
65
+ Статус: не использовать в новом коде как high-level стандарт.
66
+
67
+ Причина:
68
+ - это low-level/legacy movement components;
69
+ - для нового кода уже есть hook-first путь `useDraggableApi`, а для окон — `FloatingWindow`.
70
+
71
+
72
+ ## Pass 2 — grid helpers without grid lifecycle change
73
+
74
+ ### Log tables default column definition
75
+
76
+ Проверено:
77
+ - `src/common/src/logs/miniLogs.tsx` и `src/common/src/logs/logs.tsx` дублировали один и тот же `defaultColDef`: `headerClass`, `resizable`, centered `cellStyle`, `sortable`, `filter`, `wrapText`.
78
+
79
+ Сделано:
80
+ - оба места переведены на общий `colDefCentered` + локальный `wrapText: true`.
81
+ - `AgGridReact` намеренно оставлен на месте: перевод на `AgGridTable` может изменить тему, row selection и lifecycle, поэтому это отдельная задача после визуальной проверки.
82
+
83
+ Почему это не высосано из пальца:
84
+ - helper `colDefCentered` уже существует именно для такого dense table default;
85
85
  - замена убирает ручное дублирование, но не трогает grid lifecycle.
86
86
 
87
-
88
- ## Pass 3 — compatibility modal store controller
89
-
90
- ### `createModalElementStore` / `createModalRenderStore`
91
-
92
- Проверено:
93
- - `src/common/src/components/Modal/Modal.tsx` содержит общий `createJsxStore`, где mutable object `data` одновременно используется как render subscription target.
94
-
95
- Сделано:
96
- - прямые `renderBy(data)` / `updateBy(data)` заменены на `createUpdateApi(data)` (`dataApi.render()` / `dataApi.use()`).
97
- - публичные compatibility APIs `createModalElementStore()` и `createModalRenderStore()` не менялись.
98
-
99
- Почему это не высосано из пальца:
100
- - store уже был построен на mutable object + render subscription;
87
+
88
+ ## Pass 3 — compatibility modal store controller
89
+
90
+ ### `createModalElementStore` / `createModalRenderStore`
91
+
92
+ Проверено:
93
+ - `src/common/src/components/Modal/Modal.tsx` содержит общий `createJsxStore`, где mutable object `data` одновременно используется как render subscription target.
94
+
95
+ Сделано:
96
+ - прямые `renderBy(data)` / `updateBy(data)` заменены на `createUpdateApi(data)` (`dataApi.render()` / `dataApi.use()`).
97
+ - публичные compatibility APIs `createModalElementStore()` и `createModalRenderStore()` не менялись.
98
+
99
+ Почему это не высосано из пальца:
100
+ - store уже был построен на mutable object + render subscription;
101
101
  - `createUpdateApi` делает этот контракт явным без изменения поведения.
102
- ## Pass 4 — persisted slot controller
103
-
104
- ### `createUiSlot`
105
-
106
- Проверено:
107
- - `src/common/src/components/UiSlot/UiSlot.tsx` содержит persisted mutable store `st` из `memoryGetOrCreate` и прямые `renderBy(st)` / `updateBy(st)`.
108
-
109
- Сделано:
110
- - `createUiSlot` переведён на `createUpdateApi(st)` (`stApi.render()` / `stApi.use()`).
102
+ ## Pass 4 — persisted slot controller
103
+
104
+ ### `createUiSlot`
105
+
106
+ Проверено:
107
+ - `src/common/src/components/UiSlot/UiSlot.tsx` содержит persisted mutable store `st` из `memoryGetOrCreate` и прямые `renderBy(st)` / `updateBy(st)`.
108
+
109
+ Сделано:
110
+ - `createUiSlot` переведён на `createUpdateApi(st)` (`stApi.render()` / `stApi.use()`).
111
111
  - публичный API `Slot`, `PlacementSetting`, `getPlace`, `setPlace` не менялся.
112
- - usage example проверен: card 21 (createUiSlot - configurable block placement) уже использует публичный API; менять card не нужно, потому что refactor внутренний.
113
-
114
- Почему это не высосано из пальца:
115
- - это тот же contract, что в `useKeyboard` и compatibility modal store: mutable object + render subscription;
116
- - persistence через `memoryMarkDirty` оставлен без изменений.
117
-
118
- ## Pass 5 — toolbar density registry controller
119
-
120
- ### `registerToolbarDensity` / toolbar density consumers
121
-
122
- Оценка перед выполнением:
123
- - эффективность: medium;
124
- - простота: simple;
125
- - риск: low.
126
-
127
- Проверено:
128
- - `src/common/src/components/Toolbar/Toolbar.tsx` содержит module-level mutable registry `densities` и прямые `renderBy(densities)` / `updateBy(densities)`.
129
- - card 25 использует `registerToolbarDensity` как usage example.
130
-
131
- Сделано:
132
- - только registry `densities` переведён на `createUpdateApi(densities)` (`densitiesApi.render()` / `densitiesApi.use()`).
133
- - persisted toolbar config `st`, `sourceMode`, external `listSource`, `memoryMarkDirty` не трогались.
134
- - usage example проверен: card 25 (`createToolbar - customizable toolbar`) уже использует публичный `registerToolbarDensity`; менять card не нужно, потому что refactor внутренний.
135
-
136
- Почему это не высосано из пальца:
137
- - `densities` ровно module singleton + subscription target;
112
+ - usage example проверен: card 21 (createUiSlot - configurable block placement) уже использует публичный API; менять card не нужно, потому что refactor внутренний.
113
+
114
+ Почему это не высосано из пальца:
115
+ - это тот же contract, что в `useKeyboard` и compatibility modal store: mutable object + render subscription;
116
+ - persistence через `memoryMarkDirty` оставлен без изменений.
117
+
118
+ ## Pass 5 — toolbar density registry controller
119
+
120
+ ### `registerToolbarDensity` / toolbar density consumers
121
+
122
+ Оценка перед выполнением:
123
+ - эффективность: medium;
124
+ - простота: simple;
125
+ - риск: low.
126
+
127
+ Проверено:
128
+ - `src/common/src/components/Toolbar/Toolbar.tsx` содержит module-level mutable registry `densities` и прямые `renderBy(densities)` / `updateBy(densities)`.
129
+ - card 25 использует `registerToolbarDensity` как usage example.
130
+
131
+ Сделано:
132
+ - только registry `densities` переведён на `createUpdateApi(densities)` (`densitiesApi.render()` / `densitiesApi.use()`).
133
+ - persisted toolbar config `st`, `sourceMode`, external `listSource`, `memoryMarkDirty` не трогались.
134
+ - usage example проверен: card 25 (`createToolbar - customizable toolbar`) уже использует публичный `registerToolbarDensity`; менять card не нужно, потому что refactor внутренний.
135
+
136
+ Почему это не высосано из пальца:
137
+ - `densities` ровно module singleton + subscription target;
138
138
  - изменение уменьшает прямой `renderBy/updateBy` там, где нет persistence/grid side effects.
139
-
140
- ## Pass 6 — settings section registry controller
141
-
142
- ### `registerSettingsSection` / `SettingsDialog`
143
-
144
- Оценка перед выполнением:
145
- - эффективность: medium;
146
- - простота: medium;
147
- - риск: medium.
148
-
149
- Проверено:
150
- - `src/common/src/components/Settings/SettingsDialog.tsx` содержит module-level mutable registry `registry` и прямые `renderBy(registry)` / `updateBy(registry)`.
151
- - card 20 использует `registerSettingsSection` как usage example.
152
-
153
- Сделано:
154
- - только section registry переведён на `createUpdateApi(registry)` (`registryApi.render()` / `registryApi.use()`).
155
- - search history, tree UX, resize behavior и `settingsDialogLayout` не менялись.
156
- - usage example проверен: card 20 (`SettingsDialog - searchable settings tree + registry`) уже использует публичный `registerSettingsSection`; менять card не нужно, потому что refactor внутренний.
157
-
158
- Low-effectiveness skip:
139
+
140
+ ## Pass 6 — settings section registry controller
141
+
142
+ ### `registerSettingsSection` / `SettingsDialog`
143
+
144
+ Оценка перед выполнением:
145
+ - эффективность: medium;
146
+ - простота: medium;
147
+ - риск: medium.
148
+
149
+ Проверено:
150
+ - `src/common/src/components/Settings/SettingsDialog.tsx` содержит module-level mutable registry `registry` и прямые `renderBy(registry)` / `updateBy(registry)`.
151
+ - card 20 использует `registerSettingsSection` как usage example.
152
+
153
+ Сделано:
154
+ - только section registry переведён на `createUpdateApi(registry)` (`registryApi.render()` / `registryApi.use()`).
155
+ - search history, tree UX, resize behavior и `settingsDialogLayout` не менялись.
156
+ - usage example проверен: card 20 (`SettingsDialog - searchable settings tree + registry`) уже использует публичный `registerSettingsSection`; менять card не нужно, потому что refactor внутренний.
157
+
158
+ Low-effectiveness skip:
159
159
  - `settingsDialogLayout` пока не переводился: сейчас нет явного `updateBy(settingsDialogLayout)` consumer, а nav width живёт в React state и сохраняется через `memoryMarkDirty`. Отдельный controller здесь мало что даст без изменения layout contract.
160
-
161
- ## Pass 7 — columnState controller split
162
-
163
- ### `createColumnState` runtime `rt` and persisted `st`
164
-
165
- Оценка перед выполнением:
166
- - `rt` present/presentGate: эффективность medium, простота simple, риск low-medium;
167
- - `st` persisted config: эффективность medium, простота medium, риск medium.
168
-
169
- Проверено:
170
- - `src/common/src/grid/columnState/columnState.ts` содержит runtime store `rt` для `present` / `presentGate` и persisted store `st` для column config.
171
- - cards 29/30 используют `usePresent` / `setPresentGate`; cards 28-31 используют persisted config через `useConfig`, grid adapter, menu, toolbar source.
172
-
173
- Сделано:
174
- - `rt` переведён на `createUpdateApi(rt)` (`rtApi.render()` / `rtApi.use()`).
175
- - `st` переведён на `createUpdateApi(st)` (`stApi.render()` / `stApi.use()`).
176
- - `commit`, `memoryMarkDirty`, `applyToGrid`, `emitChange`, `listSource` и grid adapter flow не менялись.
177
- - usage examples проверены: cards 28-31 уже используют публичный `createColumnState` API; менять cards не нужно, потому что refactor внутренний.
178
-
179
- ## Pass 8 — search history controller
180
-
181
- ### `createSearchHistory`
182
-
183
- Оценка перед выполнением:
184
- - эффективность: high;
185
- - простота: simple;
186
- - риск: low.
187
-
188
- Проверено:
189
- - `src/common/src/utils/searchHistory.ts` содержит persisted mutable store `st` и прямые `renderBy(st)` / `updateBy(st)`.
190
- - `SettingsDialog` и card 20 используют этот primitive для истории поиска.
191
-
192
- Сделано:
193
- - `createSearchHistory` переведён на `createUpdateApi(st)` (`stApi.render()` / `stApi.use()`).
194
- - публичный API `items`, `use`, `add`, `remove`, `clear` не менялся.
195
- - usage docs уже рекомендуют `createSearchHistory({key})`; менять пример не нужно.
196
-
197
- ## Pass 9 — toolbar persisted config controller
198
-
199
- ### `createToolbar` local `st`
200
-
201
- Оценка перед выполнением:
202
- - эффективность: medium;
203
- - простота: medium;
204
- - риск: medium.
205
-
206
- Проверено:
207
- - `src/common/src/components/Toolbar/Toolbar.tsx` после density-registry pass всё ещё содержал persisted config store `st` с прямыми `renderBy(st)` / `updateBy(st)`.
208
- - cards 25, 30, 31 используют `createToolbar` local/external source flows.
209
-
210
- Сделано:
211
- - local toolbar store `st` переведён на `createUpdateApi(st)` (`stApi.render()` / `stApi.use()`).
212
- - external source hook `ext?.useConfig()`, `sourceMode`, `memoryMarkDirty`, `emitChange` не менялись.
160
+
161
+ ## Pass 7 — columnState controller split
162
+
163
+ ### `createColumnState` runtime `rt` and persisted `st`
164
+
165
+ Оценка перед выполнением:
166
+ - `rt` present/presentGate: эффективность medium, простота simple, риск low-medium;
167
+ - `st` persisted config: эффективность medium, простота medium, риск medium.
168
+
169
+ Проверено:
170
+ - `src/common/src/grid/columnState/columnState.ts` содержит runtime store `rt` для `present` / `presentGate` и persisted store `st` для column config.
171
+ - cards 29/30 используют `usePresent` / `setPresentGate`; cards 28-31 используют persisted config через `useConfig`, grid adapter, menu, toolbar source.
172
+
173
+ Сделано:
174
+ - `rt` переведён на `createUpdateApi(rt)` (`rtApi.render()` / `rtApi.use()`).
175
+ - `st` переведён на `createUpdateApi(st)` (`stApi.render()` / `stApi.use()`).
176
+ - `commit`, `memoryMarkDirty`, `applyToGrid`, `emitChange`, `listSource` и grid adapter flow не менялись.
177
+ - usage examples проверены: cards 28-31 уже используют публичный `createColumnState` API; менять cards не нужно, потому что refactor внутренний.
178
+
179
+ ## Pass 8 — search history controller
180
+
181
+ ### `createSearchHistory`
182
+
183
+ Оценка перед выполнением:
184
+ - эффективность: high;
185
+ - простота: simple;
186
+ - риск: low.
187
+
188
+ Проверено:
189
+ - `src/common/src/utils/searchHistory.ts` содержит persisted mutable store `st` и прямые `renderBy(st)` / `updateBy(st)`.
190
+ - `SettingsDialog` и card 20 используют этот primitive для истории поиска.
191
+
192
+ Сделано:
193
+ - `createSearchHistory` переведён на `createUpdateApi(st)` (`stApi.render()` / `stApi.use()`).
194
+ - публичный API `items`, `use`, `add`, `remove`, `clear` не менялся.
195
+ - usage docs уже рекомендуют `createSearchHistory({key})`; менять пример не нужно.
196
+
197
+ ## Pass 9 — toolbar persisted config controller
198
+
199
+ ### `createToolbar` local `st`
200
+
201
+ Оценка перед выполнением:
202
+ - эффективность: medium;
203
+ - простота: medium;
204
+ - риск: medium.
205
+
206
+ Проверено:
207
+ - `src/common/src/components/Toolbar/Toolbar.tsx` после density-registry pass всё ещё содержал persisted config store `st` с прямыми `renderBy(st)` / `updateBy(st)`.
208
+ - cards 25, 30, 31 используют `createToolbar` local/external source flows.
209
+
210
+ Сделано:
211
+ - local toolbar store `st` переведён на `createUpdateApi(st)` (`stApi.render()` / `stApi.use()`).
212
+ - external source hook `ext?.useConfig()`, `sourceMode`, `memoryMarkDirty`, `emitChange` не менялись.
213
213
  - usage examples проверены: cards 25/30/31 уже используют публичный API; менять cards не нужно, потому что refactor внутренний.
214
-
215
- ## Pass 10 — window/menu controller normalization
216
-
217
- ### `FloatingWindow` open-window registry
218
-
219
- Оценка перед выполнением:
220
- - эффективность: medium;
221
- - простота: medium;
222
- - риск: medium.
223
-
224
- Проверено:
225
- - `src/common/src/components/Dnd/FloatingWindow.tsx` содержит module-level `openWindows` registry для z-index order и прямые `renderBy(openWindows)` / `updateBy(openWindows, cb)`.
226
- - card 2 и Settings/Dialog flows используют `FloatingWindow` как usage examples.
227
-
228
- Сделано:
229
- - `openWindows` переведён на `createUpdateApi(openWindows)` (`openWindowsApi.render()` / `openWindowsApi.use(cb)`).
230
- - drag/resize geometry, document listeners, `floatingWindowMap` persistence и `DragBox` не менялись.
231
-
232
- ### `LeftModal` menu store
233
-
234
- Оценка перед выполнением:
235
- - эффективность: medium;
236
- - простота: simple;
237
- - риск: medium.
238
-
239
- Проверено:
240
- - `src/common/src/components/Modal/LeftModal.tsx` содержит local `menuStore` Map внутри `getApiLeftMenu()` и прямые `renderBy(menuStore)` / `updateBy(menuStore)`.
241
-
242
- Сделано:
243
- - `menuStore` переведён на `createUpdateApi(menuStore)` (`menuStoreApi.render()` / `menuStoreApi.use()`).
244
- - compatibility method `ApiLeftMenu.renderBy()` оставлен, но внутри вызывает `menuStoreApi.render()`.
214
+
215
+ ## Pass 10 — window/menu controller normalization
216
+
217
+ ### `FloatingWindow` open-window registry
218
+
219
+ Оценка перед выполнением:
220
+ - эффективность: medium;
221
+ - простота: medium;
222
+ - риск: medium.
223
+
224
+ Проверено:
225
+ - `src/common/src/components/Dnd/FloatingWindow.tsx` содержит module-level `openWindows` registry для z-index order и прямые `renderBy(openWindows)` / `updateBy(openWindows, cb)`.
226
+ - card 2 и Settings/Dialog flows используют `FloatingWindow` как usage examples.
227
+
228
+ Сделано:
229
+ - `openWindows` переведён на `createUpdateApi(openWindows)` (`openWindowsApi.render()` / `openWindowsApi.use(cb)`).
230
+ - drag/resize geometry, document listeners, `floatingWindowMap` persistence и `DragBox` не менялись.
231
+
232
+ ### `LeftModal` menu store
233
+
234
+ Оценка перед выполнением:
235
+ - эффективность: medium;
236
+ - простота: simple;
237
+ - риск: medium.
238
+
239
+ Проверено:
240
+ - `src/common/src/components/Modal/LeftModal.tsx` содержит local `menuStore` Map внутри `getApiLeftMenu()` и прямые `renderBy(menuStore)` / `updateBy(menuStore)`.
241
+
242
+ Сделано:
243
+ - `menuStore` переведён на `createUpdateApi(menuStore)` (`menuStoreApi.render()` / `menuStoreApi.use()`).
244
+ - compatibility method `ApiLeftMenu.renderBy()` оставлен, но внутри вызывает `menuStoreApi.render()`.
245
245
  - `createModalElementStore()` path уже был переведён раньше; меню/модалка публично не менялись.
246
246
 
247
-
248
- ## Pass 11 — log tables wrapper transition
249
-
250
- ### `PageLogs` / `MiniLogs`
251
-
252
- Оценка перед выполнением:
253
- - эффективность: medium/high;
254
- - простота: medium;
255
- - риск: medium, потому что внешний вид/theme/resize могут измениться, но QA stand это покрывает вручную.
256
-
257
- Проверено:
258
- - `src/common/src/logs/logs.tsx` и `src/common/src/logs/miniLogs.tsx` после defaultColDef pass всё ещё использовали raw `AgGridReact`.
259
- - card 9 (`Logs - time format`) использует `logsApi.React.PageLogs` и подходит для ручной проверки основного log table path.
260
-
261
- Сделано:
262
- - `PageLogs` и `MiniLogs` переведены на `AgGridTable`.
263
- - logger state/timing, `logsApi`, `MessageEventLogs`, `contextMenu` copy action, filter update path и row transaction path не менялись.
264
- - `logsContext.tsx` намеренно не трогался: это отдельный older/context logger implementation with localStorage + raw grid.
265
-
266
- Ручная проверка:
267
- - card 9: нажать `add log`, время форматируется как `HH:mm:ss`, строка появляется в таблице, правый клик по ячейке даёт copy menu.
247
+
248
+ ## Pass 11 — log tables wrapper transition
249
+
250
+ ### `PageLogs` / `MiniLogs`
251
+
252
+ Оценка перед выполнением:
253
+ - эффективность: medium/high;
254
+ - простота: medium;
255
+ - риск: medium, потому что внешний вид/theme/resize могут измениться, но QA stand это покрывает вручную.
256
+
257
+ Проверено:
258
+ - `src/common/src/logs/logs.tsx` и `src/common/src/logs/miniLogs.tsx` после defaultColDef pass всё ещё использовали raw `AgGridReact`.
259
+ - card 9 (`Logs - time format`) использует `logsApi.React.PageLogs` и подходит для ручной проверки основного log table path.
260
+
261
+ Сделано:
262
+ - `PageLogs` и `MiniLogs` переведены на `AgGridTable`.
263
+ - logger state/timing, `logsApi`, `MessageEventLogs`, `contextMenu` copy action, filter update path и row transaction path не менялись.
264
+ - `logsContext.tsx` намеренно не трогался: это отдельный older/context logger implementation with localStorage + raw grid.
265
+
266
+ Ручная проверка:
267
+ - card 9: нажать `add log`, время форматируется как `HH:mm:ss`, строка появляется в таблице, правый клик по ячейке даёт copy menu.
268
268
  - если `MiniLogs` есть в app/stand consumer, проверить: таблица растягивается по контейнеру, click callback на ячейке вызывается.
269
-
270
- ## Pass 12 — MiniLogs hook/controller layering
271
-
272
- ### `useMiniLogsTable` / `MiniLogsView` / `MiniLogsTable`
273
-
274
- Оценка перед выполнением:
275
- - эффективность: medium/high;
276
- - простота: medium;
277
- - риск: medium.
278
-
279
- Проверено:
280
- - прямых runtime-использований `MiniLogs` в repo не найдено, но public barrel уже экспортирует `miniLogs.tsx` через `src/common/api.tsx`;
281
- - card 9 покрывал `PageLogs`, но не `MiniLogs`, поэтому QA example требовал обновления;
282
- - row identity нельзя менять на `AgGridTable data={...}` / default `id`, потому логовый `id` может повторяться по source area.
283
-
284
- Сделано:
285
- - `MiniLogs` разделён на hook/controller `useMiniLogsTable`, pure visual `MiniLogsView`, convenience `MiniLogsTable` и compatibility wrapper `MiniLogs`;
286
- - hook отдаёт `props/tableProps/gridProps`, `apiRef`, `fit`, `getApi`, `withApi` и callbacks, но не создаёт внутренний `useAgGrid` controller;
287
- - сохранён `rowData` path и старый `CellMouseDownEvent<T>` click contract;
288
- - QA card 9 получил прямой `MiniLogsTable` block;
289
- - docs обновлены в `doc/EXAMPLE_USAGE.md`, `doc/wenay-react2.md`, `doc/wenay-react2-rare.md`;
290
- - добавлен `__test/miniLogs.test.tsx` на hook props/click/grid helpers.
291
-
292
- Почему store не добавлен:
293
- - MiniLogs сейчас table-view над внешним `data`; нет реального consumer для append/limit/history store;
294
- - MiniLogs-owned state лучше добавлять позже только вместе с `createLogsController` или конкретным app consumer.
295
-
296
- ## Next candidates
297
-
298
- 1. `logs.tsx` logger internals — эффективность medium, простота hard, риск medium-high. Там несколько stores, callback-subscriptions, notification timing и table rendering; не делать как small pass без отдельного logger plan.
299
- 2. `logsContext.tsx` — эффективность medium, простота hard, риск medium-high. Есть прямой `localStorage` и голый `AgGridReact`, но split нужен отдельно: persistence contract + grid lifecycle/visual check.
300
- 3. `memoryStore.tsx` direct `renderBy(cur)` — эффективность low/medium, простота medium, риск medium. Подробно:
301
- - прямой вызов есть только в `memoryUpdate(key, mutate)`: он ререндерит подписчиков именно на объект `cur`, который лежит внутри `memoryProps`;
302
- - `memoryProps` сам является `ObservableMap` и уже наблюдается `memoryCache`, поэтому `memorySet`, `memoryGetOrCreate`, `memoryMarkDirty` идут по map/cache dirty channel, а не по React-subscription API;
303
- - перевод `memoryUpdate` на `createUpdateApi(cur)` технически возможен, но почти ничего не меняет для публичного contract, потому что API создаётся на лету для произвольного stored object;
304
- - риск в том, что это core persistence helper: им пользуются toolbar/columnState/UiSlot/search history/settings/window/right menu flows, и ошибка ударит не по одному widget, а по всему сохранению UI-конфига;
305
- - делать стоит только если появится конкретный consumer/test на `memoryUpdate` или если мы явно вводим стандарт “memory object update controller” и покрываем это тестом: subscribe to stored object -> `memoryUpdate` -> rerender + `memoryCache.onDirty`.
306
- 4. `SettingsDialog.layout` controller — эффективность low, простота simple, риск low. Сейчас нет `updateBy(settingsDialogLayout)` consumer, поэтому пропущено как малоэффективное.
307
- 5. `PageVisibilityProvider` candidates — эффективность low до появления реального polling/replay/canvas consumer. Сейчас не внедрять в обычный UI ради helper.
269
+
270
+ ## Pass 12 — MiniLogs hook/controller layering
271
+
272
+ ### `useMiniLogsTable` / `MiniLogsView` / `MiniLogsTable`
273
+
274
+ Оценка перед выполнением:
275
+ - эффективность: medium/high;
276
+ - простота: medium;
277
+ - риск: medium.
278
+
279
+ Проверено:
280
+ - прямых runtime-использований `MiniLogs` в repo не найдено, но public barrel уже экспортирует `miniLogs.tsx` через `src/common/api.tsx`;
281
+ - card 9 покрывал `PageLogs`, но не `MiniLogs`, поэтому QA example требовал обновления;
282
+ - row identity нельзя менять на `AgGridTable data={...}` / default `id`, потому логовый `id` может повторяться по source area.
283
+
284
+ Сделано:
285
+ - `MiniLogs` разделён на hook/controller `useMiniLogsTable`, pure visual `MiniLogsView`, convenience `MiniLogsTable` и compatibility wrapper `MiniLogs`;
286
+ - hook отдаёт `props/tableProps/gridProps`, `apiRef`, `fit`, `getApi`, `withApi` и callbacks, но не создаёт внутренний `useAgGrid` controller;
287
+ - сохранён `rowData` path и старый `CellMouseDownEvent<T>` click contract;
288
+ - QA card 9 получил прямой `MiniLogsTable` block;
289
+ - docs обновлены в `doc/EXAMPLE_USAGE.md`, `doc/wenay-react2.md`, `doc/wenay-react2-rare.md`;
290
+ - добавлен `__test/miniLogs.test.tsx` на hook props/click/grid helpers.
291
+
292
+ Почему store не добавлен:
293
+ - MiniLogs сейчас table-view над внешним `data`; нет реального consumer для append/limit/history store;
294
+ - MiniLogs-owned state лучше добавлять позже только вместе с `createLogsController` или конкретным app consumer.
295
+
296
+ ## Next candidates
297
+
298
+ 1. `logs.tsx` logger internals — эффективность medium, простота hard, риск medium-high. Там несколько stores, callback-subscriptions, notification timing и table rendering; не делать как small pass без отдельного logger plan.
299
+ 2. `logsContext.tsx` — эффективность medium, простота hard, риск medium-high. Есть прямой `localStorage` и голый `AgGridReact`, но split нужен отдельно: persistence contract + grid lifecycle/visual check.
300
+ 3. `memoryStore.tsx` direct `renderBy(cur)` — эффективность low/medium, простота medium, риск medium. Подробно:
301
+ - прямой вызов есть только в `memoryUpdate(key, mutate)`: он ререндерит подписчиков именно на объект `cur`, который лежит внутри `memoryProps`;
302
+ - `memoryProps` сам является `ObservableMap` и уже наблюдается `memoryCache`, поэтому `memorySet`, `memoryGetOrCreate`, `memoryMarkDirty` идут по map/cache dirty channel, а не по React-subscription API;
303
+ - перевод `memoryUpdate` на `createUpdateApi(cur)` технически возможен, но почти ничего не меняет для публичного contract, потому что API создаётся на лету для произвольного stored object;
304
+ - риск в том, что это core persistence helper: им пользуются toolbar/columnState/UiSlot/search history/settings/window/right menu flows, и ошибка ударит не по одному widget, а по всему сохранению UI-конфига;
305
+ - делать стоит только если появится конкретный consumer/test на `memoryUpdate` или если мы явно вводим стандарт “memory object update controller” и покрываем это тестом: subscribe to stored object -> `memoryUpdate` -> rerender + `memoryCache.onDirty`.
306
+ 4. `SettingsDialog.layout` controller — эффективность low, простота simple, риск low. Сейчас нет `updateBy(settingsDialogLayout)` consumer, поэтому пропущено как малоэффективное.
307
+ 5. `PageVisibilityProvider` candidates — эффективность low до появления реального polling/replay/canvas consumer. Сейчас не внедрять в обычный UI ради helper.
308
308
  6. Store/listen hooks — эффективность low внутри shared library без настоящего `Observe.Store` / `listen` consumer. Больше смысла искать в QA/app examples.
309
309
 
310
- ## Verification
311
-
312
- - `npx tsc -p tsconfig.qa-check.json --noEmit` — passed after Pass 12.
310
+ ## Verification
311
+
312
+ - `npx tsc -p tsconfig.qa-check.json --noEmit` — passed after Pass 12.
313
313
  - `npm run testjest -- --runInBand miniLogs.test.tsx` — passed after Pass 12: 1 suite, 2 tests.
314
314
  - `npm run testjest -- --runInBand` — passed after Pass 12: 10 suites, 27 tests.
315
- - `npm run build` — passed after Pass 12.
315
+ - `npm run build` — passed after Pass 12.
316
316
  - `git diff --check` — passed after Pass 12; only LF/CRLF normalization warnings.
317
-
318
- ## Pass 13 — final inventory of remaining primitive-reuse candidates
319
-
320
- Дата: 2026-07-09.
321
-
322
- Цель: после hook/controller-first очереди повторно проверить широкий пункт `Недоиспользуемые методы wenay-react2` и не делать задачи ради задач.
323
-
324
- Проверено:
325
- - raw `AgGridReact`: остался только внутри самого wrapper `agGrid4.tsx` и в `src/common/testUseReact/useGrid.tsx`;
326
- - `src/common/testUseReact/useGrid.tsx` уже документирован в `doc/EXAMPLE_USAGE.md` / `doc/PROJECT_FUNCTIONALITY.md` как legacy/regression example для низкоуровневого `applyGridRows`, а не canonical grid pattern;
327
- - `logsContext.tsx` всё ещё имеет прямой `localStorage`, но это публичное legacy/compat поведение provider-а; перевод на `memoryCache` изменит contract, потому что app должен будет сам вызывать `memoryCache.load/save`;
328
- - `PageVisibilityProvider` candidates есть только в тяжёлых timer/canvas/replay/chart местах (`useReplay`, chart engines, QA replay demos), где нужно отдельное policy-решение: продолжать catch-up в hidden tab или паузить;
329
- - ручные `listen.on` / `useEffect` в QA в основном демонстрируют compatibility APIs или сами hook implementations; единственный useful cleanup — card 25 toolbar `tb.api.onChange` — безопасно переведён на `useListenEffect`;
330
- - Settings/Toolbar registries уже показаны активными QA cards 20/25/30/31; новых low-risk registry migrations без app consumer не найдено;
331
- - ModalProvider/useModal уже есть active QA card 13; imperative modal stores оставлены documented compatibility path.
332
-
333
- Решение:
334
- - `qa.tsx` card 25: `tb.api.onChange.on(...)` заменён на `useListenEffect(tb.api.onChange, ...)`;
335
- - `useGrid.tsx` не переводить на `AgGridTable`, пока он нужен как regression для `applyGridRows`;
336
- - `logsContext` storage не менять без отдельной задачи “context logger persistence contract”;
337
- - PageVisibility/replay/chart timers не менять без явного UX-policy;
338
- - broad primitive-reuse target считать выполненным на текущем repository surface: оставшиеся пункты low-effectiveness или high-risk без нового consumer/test.
339
-
340
- ## Verification update
341
-
317
+
318
+ ## Pass 13 — final inventory of remaining primitive-reuse candidates
319
+
320
+ Дата: 2026-07-09.
321
+
322
+ Цель: после hook/controller-first очереди повторно проверить широкий пункт `Недоиспользуемые методы wenay-react2` и не делать задачи ради задач.
323
+
324
+ Проверено:
325
+ - raw `AgGridReact`: остался только внутри самого wrapper `agGrid4.tsx` и в `src/common/testUseReact/useGrid.tsx`;
326
+ - `src/common/testUseReact/useGrid.tsx` уже документирован в `doc/EXAMPLE_USAGE.md` / `doc/PROJECT_FUNCTIONALITY.md` как legacy/regression example для низкоуровневого `applyGridRows`, а не canonical grid pattern;
327
+ - `logsContext.tsx` всё ещё имеет прямой `localStorage`, но это публичное legacy/compat поведение provider-а; перевод на `memoryCache` изменит contract, потому что app должен будет сам вызывать `memoryCache.load/save`;
328
+ - `PageVisibilityProvider` candidates есть только в тяжёлых timer/canvas/replay/chart местах (`useReplay`, chart engines, QA replay demos), где нужно отдельное policy-решение: продолжать catch-up в hidden tab или паузить;
329
+ - ручные `listen.on` / `useEffect` в QA в основном демонстрируют compatibility APIs или сами hook implementations; единственный useful cleanup — card 25 toolbar `tb.api.onChange` — безопасно переведён на `useListenEffect`;
330
+ - Settings/Toolbar registries уже показаны активными QA cards 20/25/30/31; новых low-risk registry migrations без app consumer не найдено;
331
+ - ModalProvider/useModal уже есть active QA card 13; imperative modal stores оставлены documented compatibility path.
332
+
333
+ Решение:
334
+ - `qa.tsx` card 25: `tb.api.onChange.on(...)` заменён на `useListenEffect(tb.api.onChange, ...)`;
335
+ - `useGrid.tsx` не переводить на `AgGridTable`, пока он нужен как regression для `applyGridRows`;
336
+ - `logsContext` storage не менять без отдельной задачи “context logger persistence contract”;
337
+ - PageVisibility/replay/chart timers не менять без явного UX-policy;
338
+ - broad primitive-reuse target считать выполненным на текущем repository surface: оставшиеся пункты low-effectiveness или high-risk без нового consumer/test.
339
+
340
+ ## Verification update
341
+
342
342
  - `npx tsc -p tsconfig.qa-check.json --noEmit` — passed after FloatingWindow / final inventory / QA listen cleanup.
343
- - `npm run testjest -- --runInBand createToolbar.test.ts` — passed after QA listen cleanup.
344
- - `npm run testjest -- --runInBand floatingWindowController.test.tsx settingsDialog.test.tsx` — passed: 2 suites, 6 tests.
345
- - `npm run testjest -- --runInBand` — passed: 14 suites, 44 tests.
346
- - `npm run build` — passed.
347
- - `git diff --check` — passed; only LF/CRLF normalization warnings.
348
- ## Pass 14 — Toolbar.Bar movement animation
349
-
350
- Дата: 2026-07-09.
351
-
352
- Задача: пользователь подтвердил card 30 как эталон и попросил такую же анимацию горизонтального меню в cards 25 и 31.
353
-
354
- Сделано:
355
- - `createToolbar().Bar` получил общий FLIP-pass (`useToolbarFlip`): при изменении order/visibility/density элементы получают временный `translate(dx,dy)` и возвращаются через `transform 180ms ease`;
356
- - card 25 and card 31 используют стандартный `Toolbar.Bar`, поэтому получили анимацию без копирования stand-only `Qa30AnimatedMenuBar`;
357
- - card 30 оставлен эталоном и не переписывался;
358
- - публичный API `createToolbar`, `ToolbarItem`, `ToolbarConfig` не менялся.
359
-
360
- Проверка:
361
- - `npx tsc -p tsconfig.qa-check.json --noEmit`;
362
- - `npm run testjest -- --runInBand createToolbar.test.ts`;
363
- - full test/build перед публикацией v1.0.40.
364
-
365
- Оценка пользы:
366
- - UI-польза: high для cards 25/31, потому order/density changes теперь визуально читаются так же, как в card 30;
367
- - архитектурная польза: medium/high, потому поведение находится в shared `Toolbar.Bar`, а не в каждом stand/example отдельно;
343
+ - `npm run testjest -- --runInBand createToolbar.test.ts` — passed after QA listen cleanup.
344
+ - `npm run testjest -- --runInBand floatingWindowController.test.tsx settingsDialog.test.tsx` — passed: 2 suites, 6 tests.
345
+ - `npm run testjest -- --runInBand` — passed: 14 suites, 44 tests.
346
+ - `npm run build` — passed.
347
+ - `git diff --check` — passed; only LF/CRLF normalization warnings.
348
+ ## Pass 14 — Toolbar.Bar movement animation
349
+
350
+ Дата: 2026-07-09.
351
+
352
+ Задача: пользователь подтвердил card 30 как эталон и попросил такую же анимацию горизонтального меню в cards 25 и 31.
353
+
354
+ Сделано:
355
+ - `createToolbar().Bar` получил общий FLIP-pass (`useToolbarFlip`): при изменении order/visibility/density элементы получают временный `translate(dx,dy)` и возвращаются через `transform 180ms ease`;
356
+ - card 25 and card 31 используют стандартный `Toolbar.Bar`, поэтому получили анимацию без копирования stand-only `Qa30AnimatedMenuBar`;
357
+ - card 30 оставлен эталоном и не переписывался;
358
+ - публичный API `createToolbar`, `ToolbarItem`, `ToolbarConfig` не менялся.
359
+
360
+ Проверка:
361
+ - `npx tsc -p tsconfig.qa-check.json --noEmit`;
362
+ - `npm run testjest -- --runInBand createToolbar.test.ts`;
363
+ - full test/build перед публикацией v1.0.40.
364
+
365
+ Оценка пользы:
366
+ - UI-польза: high для cards 25/31, потому order/density changes теперь визуально читаются так же, как в card 30;
367
+ - архитектурная польза: medium/high, потому поведение находится в shared `Toolbar.Bar`, а не в каждом stand/example отдельно;
368
368
  - performance-польза: low/medium, это не ускорение вычислений, а FLIP-анимация с одним layout read pass на изменение меню.