chore(plan): lab-split 5-phase plan
PLAN.md + 5 subplans + CONTEXT.md Strategy: Incremental | Mode: Automated | Execution: Direct Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
# Phase 4: Hash-router для sim deep-links
|
||||
|
||||
**Status:** ⬜ Not Started
|
||||
**Parent plan:** [PLAN.md](./PLAN.md)
|
||||
**Domain:** frontend
|
||||
|
||||
## Objective
|
||||
|
||||
Сделать `#sim/projectile`, `#sim/newton`, `#sim/chemsandbox` etc. → открывают конкретный sim в lab. F5 на любом deep-link восстанавливает sim. Browser back/forward переключают между симуляциями. По образцу admin-redesign Phase 1 router.
|
||||
|
||||
## Tasks
|
||||
|
||||
- [ ] В `frontend/js/labs/lab-glue.js` (или новый `frontend/js/labs/lab-router.js`):
|
||||
- На load: прочитать `location.hash`, parsr `#sim/<name>`, активировать соответствующий sim
|
||||
- Listen `hashchange`: при изменении hash → переключить sim
|
||||
- При программном переключении sim (через sim-switcher UI) → обновить hash без recursion (флаг `_routerNavigating`)
|
||||
- [ ] Map sim-name → sim-id:
|
||||
- `#sim/projectile` → activate `<div id="sim-proj">`
|
||||
- `#sim/newton` → activate `<div id="sim-dynamics">` (или какой-там)
|
||||
- Полный mapping из существующих sim-ID
|
||||
- [ ] Fallback: unknown hash → ignore (показать default sim)
|
||||
- [ ] Verify: F5 на `/lab#sim/projectile` восстанавливает projectile sim
|
||||
|
||||
## Files to Modify
|
||||
|
||||
- `frontend/js/labs/lab-glue.js` — добавить router code (~50-100L)
|
||||
- `frontend/lab.html` — без изменений (или + 1 script tag если делаем отдельный lab-router.js)
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- F5 на `/lab#sim/X` восстанавливает соответствующий sim
|
||||
- Browser back/forward переключают между sims
|
||||
- Click на sim-switcher обновляет URL (`#sim/X` в адресной строке)
|
||||
- Unknown hash (`#sim/nonexistent`) → console.warn + fallback на default
|
||||
- 5 deep-link проверены вручную (projectile, newton, chemsandbox, gas, mirror)
|
||||
|
||||
## Notes
|
||||
|
||||
### Recursion guard pattern (из admin-redesign Phase 1)
|
||||
|
||||
```js
|
||||
let _navigating = false;
|
||||
function navigateTo(simId) {
|
||||
_navigating = true;
|
||||
location.hash = '#sim/' + simId;
|
||||
setTimeout(() => { _navigating = false; }, 0);
|
||||
activateSim(simId);
|
||||
}
|
||||
window.addEventListener('hashchange', () => {
|
||||
if (_navigating) return;
|
||||
const m = location.hash.match(/^#sim\/([\w-]+)/);
|
||||
if (m) activateSim(m[1]);
|
||||
});
|
||||
```
|
||||
|
||||
### Reference
|
||||
|
||||
`frontend/js/admin/router.js` (admin-redesign Phase 1) — read for inspiration. Adapt to lab context.
|
||||
|
||||
## Review Checklist
|
||||
|
||||
- [ ] Hash deep-link работает для 5 проверенных симов
|
||||
- [ ] Browser back/forward работают
|
||||
- [ ] No console errors
|
||||
- [ ] No infinite-loop при программной активации
|
||||
- [ ] Pre-commit hook passes
|
||||
|
||||
## Handoff to Next Phase
|
||||
|
||||
<!-- Implementer: full mapping #sim/X → sim-ID для Phase 5 (template lazy). -->
|
||||
Reference in New Issue
Block a user