pf_app
Named layouts lived in localStorage: invisible to anyone else, gone on the next machine, and nothing to publish from. The one server-side layout was pf.source.default_layout -- a single anonymous blob any account could overwrite for every account, which is a published layout with no owner. pf.layout replaces both. A layout is named, owned, and either private or published; published ones are listed by everyone on the forecast and writable only by their owner or an admin, the same rule pf.log already uses for its entries. Scope is the version, since that is the entry point, with version_id NULL for the source-wide default a new version inherits. Applying is never restricted -- Save is withheld on a layout that is not yours, Save as forks it -- because the guarantee wanted is that a published layout cannot be changed out from under people, not that it cannot be adapted. The toolbar's flat chip row becomes one Layout menu: Published and Mine, rename/publish/default/delete shown only where they would be allowed, and a dirty dot computed by comparing the live config against the one the pivot was applied from, since restore() fires the change event itself. Existing localStorage lists are lifted into pf.layout on first load. PUT /sources/:id/default-layout is removed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| lib | ||
| public | ||
| routes | ||
| setup_sql | ||
| ui | ||
| .env.example | ||
| .gitignore | ||
| CLAUDE.md | ||
| install.sh | ||
| package-lock.json | ||
| package.json | ||
| PERSPECTIVE.md | ||
| pf_perspective_options.md | ||
| pf_spec.md | ||
| pf.sh | ||
| server.js | ||