@praxisui/dynamic-form 9.0.66 → 9.0.68-rc.0
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.
- package/README.md +170 -0
- package/ai/component-registry.json +32 -16
- package/docs/actions-optional-text-validation-2026-09-08.md +49 -0
- package/docs/dynamic-form-authoring-document-semantics.md +105 -0
- package/docs/entity-read-feedback.md +162 -0
- package/docs/layout-apply-save-reopen-2026-09-08.md +114 -0
- package/docs/layout-toolbar-accessibility-2026-09-08.md +57 -0
- package/docs/master-detail-customization-matrix-2026-09-08.md +182 -0
- package/docs/schema-loading-recovery.md +74 -0
- package/docs/section-spacing-authoring-2026-09-08.md +61 -0
- package/fesm2022/praxisui-dynamic-form.mjs +3730 -2320
- package/package.json +8 -8
- package/src/lib/config-editor/praxis-dynamic-form-config-editor.json-api.md +28 -0
- package/src/lib/layout-editor/praxis-layout-editor.json-api.md +8 -4
- package/src/lib/praxis-dynamic-form.json-api.md +31 -3
- package/types/praxisui-dynamic-form.d.ts +140 -11
|
@@ -64,6 +64,14 @@ Essa regra evita perda silenciosa do contrato canonico de Entity Lookup durante
|
|
|
64
64
|
- IDs de linha devem ser únicos dentro da seção e IDs de coluna devem ser únicos dentro da linha;
|
|
65
65
|
- o estado `dirty` desses editores é reversível: restaurar o snapshot inicial deve desabilitar novamente Apply/Save.
|
|
66
66
|
|
|
67
|
+
## Responsive column values
|
|
68
|
+
|
|
69
|
+
The canonical grid uses integer values: `span` 1..12, `offset` 0..11 and `order` -12..12 for `xs`, `sm`, `md`, `lg` and `xl`. A missing or null value inherits the preceding breakpoint; XS defaults are 12, 0 and 0 respectively. These ranges validate each property independently; they do not impose `span + offset <= 12`.
|
|
70
|
+
|
|
71
|
+
Column controls, authoring-document validation and layout/config validation share the same domains. JSON Apply revalidates the current text before loading or emitting it, even if an earlier draft was valid. Diagnostics identify the property and breakpoint path. The AI `layout.column.add` input declares `span` as an integer. Invalid drafts are not silently rewritten; the editor withholds its preview and numeric summaries until corrected.
|
|
72
|
+
|
|
73
|
+
Core runtime resolvers recover malformed input into supported CSS grid values without mutating the source document. This is defensive rendering, not approval to save that input. Visibility commands preserve geometry and style; hiding XS/SM also preserves the previously effective MD visibility so inheritance does not unexpectedly hide larger screens.
|
|
74
|
+
|
|
67
75
|
## Visual Blocks Inside Layout
|
|
68
76
|
|
|
69
77
|
Blocos visuais dentro de seção, linha ou coluna devem seguir a decisão
|
|
@@ -102,3 +110,100 @@ Guardrail permanente:
|
|
|
102
110
|
|
|
103
111
|
Em fase beta, não vamos deixar legado para trás sem migração, mas também não
|
|
104
112
|
vamos manter legado como contrato paralelo permanente.
|
|
113
|
+
|
|
114
|
+
## Preferência inicial de apresentação
|
|
115
|
+
|
|
116
|
+
`bindings.presentationModeGlobal?: boolean | null` materializa no documento o input já existente do Dynamic Form. `true` solicita apresentação em `view`, `false` força campos e `null`/ausência herda `layoutPolicy`. A apresentação não altera `mode`; `create` e `edit` continuam permitindo preenchimento.
|
|
117
|
+
|
|
118
|
+
O editor Geral oferece ambas as escolhas. O wrapper do Page Builder publica a preferência nos inputs do widget sem persistir uma projeção de schema vazia. O editor aberto pelo runtime salva o snapshot completo de bindings em `form-inputs` e emite os bindings no patch parcial ao host. Em `input-first`, preferências locais não sobrescrevem os inputs. Omitir a preferência em replace-all limpa o override anterior.
|
|
119
|
+
|
|
120
|
+
Estilos permanecem em `contextSnapshot.presentation`, acessível pela aba **Estilo da apresentação** nos editores direto e do Page Builder. O input `presentation?: DynamicFormPresentationSnapshot | null` projeta esse bloco no widget, sem criar `config.sections` vazias; `null` limpa ajustes explícitos, enquanto ausência mantém a resolução padrão. O wrapper de Filter Form compartilha o documento, mas não oferece a ativação, pois seu runtime não implementa apresentação.
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
### Presentation style projection and editor UX
|
|
124
|
+
|
|
125
|
+
- `contextSnapshot.presentation` is the canonical style snapshot. The optional runtime input `presentation: DynamicFormPresentationSnapshot | null` projects it into page widgets independently of schema-generated `config`. Explicit styles take precedence over stored style preferences; `null` restores defaults and blocks stale stored overrides; omission retains normal style resolution.
|
|
126
|
+
- Runtime editor Apply/Save emits `presentation` with `mode` and `presentationModeGlobal` in `configPatchChange.inputPatch`. Widget save/reopen preserves the same snapshot; omitting the document block clears the widget projection with `null`.
|
|
127
|
+
- Numeric font sizes and label widths are pixels. Capturing a runtime `rem` size converts it using the host root font size; opening and saving must not reinterpret `0.78rem` as `0.78px`.
|
|
128
|
+
- **Geral → Dados do formulário** separates **Criar / Editar / Visualizar** from **Automático / Campos / Apresentação**. Selecting presentation in Create/Edit keeps the operation unchanged and explains the inactive state with an explicit action to switch to View.
|
|
129
|
+
- **Estilo da apresentação** remains discoverable regardless of the current mode. It previews sample data and does not activate presentation by itself. Filter Form does not expose this tab because it has no presentation runtime.
|
|
130
|
+
- Applying or finishing widget editing updates the page draft. **Salvar página** persists the composition. Shortening sample text affects the preview only.
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
### Page Builder: effective layout and authored input
|
|
134
|
+
|
|
135
|
+
The widget config editor receives the live `config` through the component editor's transient
|
|
136
|
+
`contextResolver`. Its sections and API field metadata are available for editing without turning
|
|
137
|
+
schema materialization into persisted page input. Opening, cancelling, or changing only mode or
|
|
138
|
+
presentation does not copy generated sections, schema hashes, hooks, or field metadata into the page.
|
|
139
|
+
|
|
140
|
+
An explicit section/row/column change projects the edited `sections` into authored `inputs.config`.
|
|
141
|
+
When the existing `layoutPolicy.source` is `schema`, this layout edit changes it to `authored`,
|
|
142
|
+
preserving the other policy settings. Reload reconciles current API metadata with the saved layout;
|
|
143
|
+
it does not store the selected record as an authoring snapshot. The intended contract preserves authored configuration and explicit property removals, storing
|
|
144
|
+
per-field overrides by canonical field name rather than the untouched API catalog. The
|
|
145
|
+
[corporate integrity review](../test-dev/corporate-integrity-review-2026-09-08.md)
|
|
146
|
+
recorded gaps in partial schemas, visual override materialization and automatic presentation.
|
|
147
|
+
Those gaps were corrected with the focused validation documented in
|
|
148
|
+
[the implementation evidence](../test-dev/corporate-integrity-fixes-2026-09-08.md).
|
|
149
|
+
The original browser demonstration with explicit presentation alone was not proof of these cases.
|
|
150
|
+
|
|
151
|
+
The Layout palette lists only eligible API fields that are not already positioned. An empty palette
|
|
152
|
+
with an allocated catalog says that all available fields are already in the layout; it does not imply
|
|
153
|
+
that the resource schema could not be loaded.
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
The wrapper also exposes the existing `configPersistenceStrategy` as **Fonte da configuração**.
|
|
157
|
+
**Definida nesta página** selects `input-first`; **Preferências salvas** selects `local-first`.
|
|
158
|
+
The runtime default remains `local-first`. When the goal is a page-owned layout, select `input-first`
|
|
159
|
+
so an older saved form preference does not replace the correctly persisted page sections on reload.
|
|
160
|
+
Changing only the source preserves the authored page config even if the currently displayed effective
|
|
161
|
+
layout came from older local preferences. This is an existing runtime input, not a new persistence
|
|
162
|
+
channel or authoring operation.
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
### Governed field overrides and partial operation schemas
|
|
166
|
+
|
|
167
|
+
The effective editor catalog is a projection, not the complete authored document.
|
|
168
|
+
Editing a field must preserve authored overrides for fields absent from both the
|
|
169
|
+
current catalog and its initial baseline. A field present in the baseline and
|
|
170
|
+
explicitly deleted from the edited document may have its authored override removed.
|
|
171
|
+
Reintroducing a schema field into the layout remains a separate layout operation.
|
|
172
|
+
|
|
173
|
+
With `layoutPolicy.source='schema'`, permitted visual overrides (for example
|
|
174
|
+
`placeholder` and `width`) are reconciled before layout materialization through
|
|
175
|
+
Core's `applyLocalFormCustomizations`. They must not disappear on reload. This
|
|
176
|
+
uses the same server-ownership rules as authored layouts: server labels,
|
|
177
|
+
requiredness, visibility and field access cannot be overridden through a local
|
|
178
|
+
widget document. The existing `field.label.set` and `field.required.set` authoring
|
|
179
|
+
operations remain valid for locally owned fields; persisting those properties
|
|
180
|
+
is not evidence that a schema-governed runtime may supersede backend semantics.
|
|
181
|
+
|
|
182
|
+
Detaching geometry from schema ownership preserves the existing detail intent
|
|
183
|
+
and automatic presentation. Explicit `presentationModeGlobal=false` still asks
|
|
184
|
+
for readonly controls; edit/create still use input mode. No business operation,
|
|
185
|
+
submit endpoint or command policy is changed by moving a field.
|
|
186
|
+
|
|
187
|
+
Validation must follow editor output through JSON serialization and runtime schema
|
|
188
|
+
rehydration, in addition to checking the emitted document. The precedence matrix
|
|
189
|
+
also supplies an older conflicting preference through `AsyncConfigStorage` with
|
|
190
|
+
`layoutPolicy.persistence='authorable'`: `input-first` keeps the page layout and
|
|
191
|
+
visual override, while `local-first` uses the saved preference. Both cases reopen
|
|
192
|
+
the wrapper against the resulting runtime config and verify that a no-op save
|
|
193
|
+
preserves the authored page document instead of copying the effective preference.
|
|
194
|
+
Transient layouts skip that preference read and cannot prove this conflict case.
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
Integrity review validation (2026-09-08): 32 focal tests passed across the widget
|
|
198
|
+
config editor, schema layout policy, and external config hydration suites. The
|
|
199
|
+
reorder round-trip includes automatic detail presentation after the saved layout
|
|
200
|
+
becomes authored. The tests also preserve server readonly authority against a
|
|
201
|
+
conflicting canonical local value. Package builds and live browser validation are
|
|
202
|
+
tracked by the integration review; this focal run does not claim those gates.
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
Conflicting preference regression: the external config hydration suite passed all
|
|
206
|
+
11 tests, including the two strategy cases with conflicting order, section title,
|
|
207
|
+
and placeholder (log `/private/tmp/praxis-form-preference-conflict-tests.log`). This
|
|
208
|
+
is an isolated storage-service test and serialized widget round-trip; actual
|
|
209
|
+
backend persistence and visual editor interaction are validated separately.
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# Feedback local na troca de registro
|
|
2
|
+
|
|
3
|
+
Estado consolidado em 08/09/2026: feedback local, erro/retry, recuperação de foco
|
|
4
|
+
e ocultação sem transição implementados e validados. As seções de evidência abaixo
|
|
5
|
+
são cronológicas; contagens, limitações e ausência de gravação pertencem à etapa
|
|
6
|
+
descrita, não substituem resultados posteriores. A configuração da página real foi
|
|
7
|
+
aplicada na etapa de [apresentação do cabeçalho](../../praxis-core/docs/widget-header-presentation-followup.md).
|
|
8
|
+
Consulte a [revisão final de documentação e skills](../../praxis-core/docs/widget-identity-documentation-review.md)
|
|
9
|
+
para o estado das orientações canônicas e seus limites de validação.
|
|
10
|
+
|
|
11
|
+
## Escopo e inventário
|
|
12
|
+
|
|
13
|
+
Mudança transversal pelo consumo do Dynamic Form em páginas, widgets e diálogos,
|
|
14
|
+
sem novos inputs, outputs, opções de editor ou contratos HTTP. Fonte canônica:
|
|
15
|
+
`PraxisDynamicForm.loadEntity`; consumidores continuam usando `resourceId`.
|
|
16
|
+
|
|
17
|
+
A pendência de hidratação, os eventos `loadingStateChange` e o cancelamento da
|
|
18
|
+
leitura já existiam. Aderência: `ja-suportado-mal-nomeado-ou-mal-materializado`
|
|
19
|
+
para feedback; `suportado-parcialmente` para falha e recuperação.
|
|
20
|
+
|
|
21
|
+
## Comportamento
|
|
22
|
+
|
|
23
|
+
- Durante a leitura, o corpo mantém geometria e componentes montados, mas fica
|
|
24
|
+
totalmente transparente, `inert` e `aria-hidden`. O status local fica fora da
|
|
25
|
+
região marcada `aria-busy`, permitindo anunciar o carregamento.
|
|
26
|
+
- Não usar apenas `visibility:hidden`: campos podem definir `visibility:visible`
|
|
27
|
+
e reaparecer. Essa situação foi detectada e corrigida no navegador real.
|
|
28
|
+
- Erros e respostas inválidas mantêm o corpo e o envio bloqueados. A ação local
|
|
29
|
+
de nova tentativa invalida a deduplicação e lê novamente a identidade atual.
|
|
30
|
+
- O sucesso substitui o snapshot com `form.reset(normalized)`, limpando valores
|
|
31
|
+
ausentes em vez de carregar campos da pessoa anterior. Leituras substituídas
|
|
32
|
+
continuam canceladas; alteração de identidade durante hooks cancela o envio.
|
|
33
|
+
- Criação e snapshots locais authorados por `initialValue` preservam seu fluxo.
|
|
34
|
+
|
|
35
|
+
## Validação
|
|
36
|
+
|
|
37
|
+
A bateria focal de seleção, runtime/submit, external-config-hydration e
|
|
38
|
+
first-config-hydration passou com 238 testes. Build oficial focal:
|
|
39
|
+
`npm run build:praxis-dynamic-form`, sucesso. Logs locais:
|
|
40
|
+
`/tmp/praxis-entity-read-tests-final.log` e `/tmp/praxis-entity-read-build.log`.
|
|
41
|
+
Após separar o status da região `aria-busy`, os 11 testes de seleção foram
|
|
42
|
+
reexecutados e passaram (`/tmp/praxis-entity-read-a11y-final.log`). Essa execução
|
|
43
|
+
recompilou o template final; o build de pacote precedeu esse último ajuste ARIA.
|
|
44
|
+
|
|
45
|
+
Foram acrescentados testes para ocultação sem desmontar, erro e retry pelo botão,
|
|
46
|
+
bloqueio de submit após erro, resposta parcial, resposta inválida, B tardio após C
|
|
47
|
+
e troca de identidade durante hooks. Os casos existentes cobrem limpar seleção,
|
|
48
|
+
cancelamento e preservação de criação/initialValue. Dois fixtures visuais
|
|
49
|
+
inicialmente falharam por inicialização incompleta; foram corrigidos antes da
|
|
50
|
+
bateria final.
|
|
51
|
+
|
|
52
|
+
CUA em `localhost:4003/page-builder-ia`, sem interceptação de rede: troca real
|
|
53
|
+
entre funcionários, cabeçalho imediato, corpo anterior oculto, status local e
|
|
54
|
+
conteúdo atualizado após sucesso. Conferidos desktop escuro e 390×844 em tema
|
|
55
|
+
claro; árvore de acessibilidade durante loading sem os campos anteriores. Tema,
|
|
56
|
+
viewport e modo de edição restaurados. Nenhum registro ou página remota foi salvo.
|
|
57
|
+
Falha/retry foi validada por teste de componente, sem provocar erro no backend
|
|
58
|
+
real. Não foi realizada sessão com leitor de tela nem publicação de pacotes.
|
|
59
|
+
|
|
60
|
+
## Artefatos derivados
|
|
61
|
+
|
|
62
|
+
README atualizado. Não houve alteração de public-api, shapes de configuração,
|
|
63
|
+
operações de authoring ou portas: não há novo campo didático no editor nem novo
|
|
64
|
+
link a apresentar. Manifestos AI, registry e corpus HTTP não exigem regeneração.
|
|
65
|
+
Naquela etapa, o guidance instalado de runtime mencionava apenas bloqueio durante pending; a
|
|
66
|
+
família correspondente não está disponível em `codex-skills/` deste checkout
|
|
67
|
+
do monorepo. A sincronização dessa orientação ficou registrada, sem editar só
|
|
68
|
+
a cópia instalada nem criar outra skill paralela. A revisão final localizou a
|
|
69
|
+
fonte em `praxis-codex-skills` e resolveu essa lacuna na skill existente de runtime.
|
|
70
|
+
|
|
71
|
+
## Prova visual adicional de falha e recuperação
|
|
72
|
+
|
|
73
|
+
O laboratório `/dynamic-page-lab` agora inclui o painel “Validação técnica:
|
|
74
|
+
atualização e recuperação do formulário”. O componente
|
|
75
|
+
`src/app/features/dynamic-page-lab/form-entity-read-proof.component.ts` usa
|
|
76
|
+
`PraxisDynamicForm` e `WidgetShellComponent` reais, com um `HttpBackend` controlado
|
|
77
|
+
e restrito à instância da prova. Não envia HTTP nem modifica registros/configuração.
|
|
78
|
+
Os controles de demonstração completam ou falham a leitura explicitamente;
|
|
79
|
+
não há timers que tornem a inspeção visual dependente da velocidade do operador.
|
|
80
|
+
|
|
81
|
+
Validação via CUA:
|
|
82
|
+
|
|
83
|
+
- Ana carregada → Bruno pendente → falha: cabeçalho Bruno, mensagem local e
|
|
84
|
+
botão de nova tentativa; valores anteriores ausentes da árvore acessível.
|
|
85
|
+
- Enter em “Tentar novamente”: contagem de leituras 2 → 3; após concluir, nome e
|
|
86
|
+
contato são de Bruno. O transporte real da API não foi exercitado neste cenário.
|
|
87
|
+
- Erro em 390×844, tema escuro: mensagem quebra em duas linhas, botão visível,
|
|
88
|
+
sem sobreposição; Tab alcança o elemento seguinte.
|
|
89
|
+
- Bruno → Ana → limpar durante pendência: leitura cancelada, nenhum pedido
|
|
90
|
+
pendente e estado de seleção vazia visível. Foco permaneceu em “Limpar seleção”.
|
|
91
|
+
- O servidor Angular recompilou a demonstração. Não foi reexecutada a bateria
|
|
92
|
+
de runtime nem o build de pacote, pois esta etapa só adicionou o consumidor de
|
|
93
|
+
laboratório e documentação. `resourceId` vazio usa `undefined`, conforme o
|
|
94
|
+
tipo público atual; o runtime normaliza essa ausência para seleção vazia.
|
|
95
|
+
|
|
96
|
+
### Pendência encontrada: foco após retry
|
|
97
|
+
|
|
98
|
+
Ao acionar “Tentar novamente” por Enter, o botão é removido durante o loading e
|
|
99
|
+
o foco retorna ao documento. A recuperação de dados funciona, mas essa transição
|
|
100
|
+
de foco ainda precisa ser corrigida no Dynamic Form e coberta por teste. O
|
|
101
|
+
critério recomendado é manter orientação dentro do detalhe quando a nova
|
|
102
|
+
tentativa foi explicitamente acionada, sem roubar o foco de quem mudou a seleção
|
|
103
|
+
ou navegou para outro controle durante a leitura. Esta prova não equivale a uma
|
|
104
|
+
certificação completa com leitor de tela.
|
|
105
|
+
|
|
106
|
+
### Correção e validação do foco
|
|
107
|
+
|
|
108
|
+
A pendência acima foi corrigida no Dynamic Form. A região estável “Dados do
|
|
109
|
+
registro”, com `tabindex=-1`, recebe foco somente na nova tentativa explicitamente
|
|
110
|
+
acionada. Permanece montada no carregamento, erro e sucesso. A resposta não chama
|
|
111
|
+
focus, portanto não retira o foco de quem navegou para outro controle. Uma região
|
|
112
|
+
live persistente anuncia carregamento, erro e sucesso; o texto visual duplicado
|
|
113
|
+
fica fora da árvore acessível. Strings disponíveis em português e inglês.
|
|
114
|
+
|
|
115
|
+
A bateria de runtime/submit/hidratação passou com **240 testes**. Depois do ajuste
|
|
116
|
+
final para evitar texto duplicado, os **13 testes de seleção** foram reexecutados
|
|
117
|
+
e passaram, assim como o build final do pacote. Logs:
|
|
118
|
+
`/tmp/praxis-retry-focus-tests.log`, `/tmp/praxis-retry-focus-final.log` e
|
|
119
|
+
`/tmp/praxis-retry-focus-build-final.log`.
|
|
120
|
+
|
|
121
|
+
CUA confirmou Enter em retry com foco na região de dados no desktop e em 390×844;
|
|
122
|
+
após concluir a leitura, a árvore acessível contém “Dados atualizados” e os valores
|
|
123
|
+
atuais. Preservação do foco até a resposta e não interferência após navegação para
|
|
124
|
+
outro controle foram verificadas com DOM real nos testes de componente. Não houve
|
|
125
|
+
sessão com leitor de tela. Nenhuma configuração remota foi gravada.
|
|
126
|
+
|
|
127
|
+
## Inventário histórico da evolução de apresentação e integração
|
|
128
|
+
|
|
129
|
+
Inventário inicial, sem novo contrato criado nessa etapa. Vazio, subtítulo
|
|
130
|
+
condicional, formatação e ações estreitas foram posteriormente tratados conforme
|
|
131
|
+
o relatório de apresentação do cabeçalho vinculado acima; a tabela registra a
|
|
132
|
+
decisão anterior à implementação, não pendências atuais.
|
|
133
|
+
|
|
134
|
+
| Necessidade | Aderência e fonte existente | Trabalho restante |
|
|
135
|
+
| --- | --- | --- |
|
|
136
|
+
| Detalhe sem seleção | Já suportado pelo `emptyState` do formulário | Compor a mensagem adequada da página |
|
|
137
|
+
| Cabeçalho vazio mostrando separador | Suportado parcialmente: interpolação de caminhos em Core, sem composição condicional do subtítulo | Auditar materializações/transformações canônicas antes de propor fallback público |
|
|
138
|
+
| Nascimento/CPF no cabeçalho | Suportado parcialmente: `ValuePresentationConfig`/resolver de Core e máscaras de exibição de Dynamic Fields; shell recebe texto | Definir como a apresentação governada chega ao título/subtítulo sem acoplar o shell a funcionário |
|
|
139
|
+
| Ações em largura estreita | Já suportado, mal materializado: shell possui grupos de ações e quebra de linha | Projetar prioridade/overflow no owner Core e conferir editor aberto |
|
|
140
|
+
|
|
141
|
+
Mapa de impacto da próxima evolução: Core (shell/composição), Page Builder
|
|
142
|
+
(editor/capabilities caso haja opção nova), Dynamic Fields (reuso de apresentação),
|
|
143
|
+
consumidor oficial e documentação pública. Qualquer mudança no shape do shell
|
|
144
|
+
exige plano de contrato público, testes de round-trip e revisão de manifestos e
|
|
145
|
+
playgrounds antes da implementação. O inventário acima não declara ainda uma
|
|
146
|
+
lacuna real de contrato.
|
|
147
|
+
|
|
148
|
+
Para integrar esta correção, revisar em conjunto o runtime/template/SCSS/i18n e
|
|
149
|
+
spec de seleção de Dynamic Form, seu README e este documento, mais o componente
|
|
150
|
+
de prova e sua inclusão no Dynamic Page Lab. O checkout contém alterações de
|
|
151
|
+
outras tarefas, inclusive nos mesmos arquivos; não incluir o diretório inteiro
|
|
152
|
+
automaticamente em commit/PR. Nenhum commit, push ou publicação foi executado.
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
## Ocultação sem transição entre identidades
|
|
156
|
+
|
|
157
|
+
Durante leitura pendente ou falha, o elemento `form` também recebe `transition:
|
|
158
|
+
none`. A opacidade zero deve ser efetiva no primeiro frame: animações de saída
|
|
159
|
+
não podem manter o registro anterior parcialmente visível sob o novo cabeçalho.
|
|
160
|
+
Ao concluir, o override transitório é removido. `inert`, `aria-hidden` e a reserva
|
|
161
|
+
de espaço continuam ativos durante a espera. A regra pertence ao Dynamic Form,
|
|
162
|
+
não à página consumidora, e não acrescenta configuração pública ou texto novo.
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# Form layout: Apply, Save and reopen
|
|
2
|
+
|
|
3
|
+
## Scope and isolation
|
|
4
|
+
|
|
5
|
+
Classification: `docs-apenas` for the repository changes. The operational proof
|
|
6
|
+
reused `/remote-config-storage-persistence-lab` without changing production code,
|
|
7
|
+
routes, providers or contracts. Existing editor documents, configuration storage
|
|
8
|
+
and widget identities already support the journey; no new contract was required.
|
|
9
|
+
|
|
10
|
+
The original `/page-builder-ia` document remained at version 92. Its payload was
|
|
11
|
+
copied through the reference Config API into the existing lab's session identity,
|
|
12
|
+
after a GET confirmed that the target did not exist (404):
|
|
13
|
+
|
|
14
|
+
- Component type: `praxis-dynamic-page`.
|
|
15
|
+
- Component ID: `dynamic-page:remote-canvas-resize-proof:ik=bf5a3dd8-27c8-4aed-b367-afffd680794f`.
|
|
16
|
+
- Lab tenant/user: `demo` / `codex-remote-persistence-lab`, environment `local`.
|
|
17
|
+
- UI tab: 15, opened on the existing remote persistence lab.
|
|
18
|
+
|
|
19
|
+
Every widget key and matching composition/canvas reference was remapped. Form ID,
|
|
20
|
+
table ID and component-instance IDs also received the run UUID. The original
|
|
21
|
+
resource paths, layouts and modes were retained. The setup PUT created version 1;
|
|
22
|
+
it was fixture preparation, not an action performed in the visual editor. All
|
|
23
|
+
subsequent layout edits and saves used the actual UI. This proves the embedded
|
|
24
|
+
Form + DynamicWidgetPage + ApiConfigStorage path, not the complete Page Builder
|
|
25
|
+
host/agentic-document path used by `/page-builder-ia`.
|
|
26
|
+
|
|
27
|
+
## Observed journey
|
|
28
|
+
|
|
29
|
+
1. Reloaded the lab and opened its proof. Status became **restaurada**. Selected
|
|
30
|
+
Ayla, opened **Configurar formulário → Layout**.
|
|
31
|
+
2. Moved Nome Completo right of CPF using the column menu and clicked **Aplicar**.
|
|
32
|
+
The displayed detail changed and the page host reported unsaved changes.
|
|
33
|
+
3. Moved Nome Completo left again, then cancelled and confirmed **Descartar
|
|
34
|
+
rascunho**. The already-applied CPF → Nome Completo order remained visible and
|
|
35
|
+
was reconstructed when reopening Layout. This exercises opening A → draft B
|
|
36
|
+
→ Apply B → draft A → discard A, without treating Apply as a remote save.
|
|
37
|
+
4. Read the copy through the API: it still exactly matched seeded version 1.
|
|
38
|
+
5. Moved Email after Telefone in Contato and used **Salvar e fechar** in the Form
|
|
39
|
+
editor. Then used **Salvar layout de teste** in the page host. Status became
|
|
40
|
+
**salva** after the host saved and read back its document.
|
|
41
|
+
6. A separate GET returned version 2 with a changed ETag. The persisted layout
|
|
42
|
+
contained CPF → Nome Completo and Telefone → Email. The contact-column widths
|
|
43
|
+
travelled with their columns (Telefone 4/12, Email 8/12). Mode remained `view`,
|
|
44
|
+
presentation remained `true`, all five composition links matched the seed,
|
|
45
|
+
and page state remained `{ "values": {} }`.
|
|
46
|
+
7. Reloaded the browser and reopened the proof. After loading completed, status
|
|
47
|
+
was **restaurada** and the empty-selection instruction appeared. Keyboard
|
|
48
|
+
selection subsequently loaded Ayla. Both edited orders were present in the
|
|
49
|
+
rendered detail and in the reopened Layout editor. A stabilized General tab
|
|
50
|
+
showed **Visualizar** and **Apresentação** checked.
|
|
51
|
+
|
|
52
|
+
Final GETs confirmed that the original was unchanged at version 92 and the copy
|
|
53
|
+
was unchanged at version 2 after reload and selection. No employee write command
|
|
54
|
+
was executed. The copy is retained under the owned identity above for review and
|
|
55
|
+
the selection investigation; it is not a published preset.
|
|
56
|
+
|
|
57
|
+
## Separate selection observation
|
|
58
|
+
|
|
59
|
+
Do not certify the entire interaction flow as defect-free. After reload, pointer
|
|
60
|
+
actions on the selection radio sometimes produced a visually checked radio while
|
|
61
|
+
the table's selection announcement/action availability and detail remained empty.
|
|
62
|
+
A later snapshot showed radio 194 checked while the status still described record
|
|
63
|
+
193 deselected with zero selections. A click on the Sol row's text also did not
|
|
64
|
+
replace Ayla's detail. Pressing Space on radio 193 did publish selection and load
|
|
65
|
+
the detail correctly.
|
|
66
|
+
|
|
67
|
+
The saved configuration still enables row-click selection and all five links are
|
|
68
|
+
unchanged. Therefore loss of the persisted link is not supported by the evidence.
|
|
69
|
+
The lab holds page customization enabled; pointer interception, radio native
|
|
70
|
+
activation versus Table selection, and interaction timing remain candidates to
|
|
71
|
+
distinguish. No runtime root cause is established, and no speculative patch was
|
|
72
|
+
made. A transient selector deadline while loading the empty state was followed by
|
|
73
|
+
a snapshot proving that the state was present; it is not evidence of a lost
|
|
74
|
+
empty-state setting. Initial immediate mode snapshots also preceded panel
|
|
75
|
+
rendering; the stabilized General tab confirmed both modes.
|
|
76
|
+
|
|
77
|
+
Follow-up: the radio inconsistency was subsequently reproduced in standalone
|
|
78
|
+
Table DOM tests and corrected at its Material `change` handler. The retained
|
|
79
|
+
copy passed pointer selection, switching records, repeated activation, Space
|
|
80
|
+
clear and row-cell selection; see the
|
|
81
|
+
[radio selection evidence](../../praxis-table/test-dev/radio-pointer-selection-2026-09-08.md).
|
|
82
|
+
This establishes the reproduced radio cause without attributing earlier browser
|
|
83
|
+
crashes to it.
|
|
84
|
+
|
|
85
|
+
The follow-up also found an error in this run's fixture preparation: it had added
|
|
86
|
+
`componentInstanceId` to Rich Content, which does not declare that input. On a
|
|
87
|
+
fresh dev load, metadata validation rejected it. A separate If-Match-protected
|
|
88
|
+
fixture correction removed only this input and advanced the copy to version 3;
|
|
89
|
+
all saved layouts, links and Table/Form identities were preserved. Version 2 is
|
|
90
|
+
the historical UI-save receipt above; version 3 is the corrected retained copy.
|
|
91
|
+
The original page remained unchanged at version 92.
|
|
92
|
+
|
|
93
|
+
## Evidence and validation limits
|
|
94
|
+
|
|
95
|
+
Read-only receipts/snapshots from this run:
|
|
96
|
+
|
|
97
|
+
- `/tmp/praxis-layout-roundtrip-owned.json`: ownership, initial status and ETag.
|
|
98
|
+
- `/tmp/praxis-layout-roundtrip-seed.json`: version 1.
|
|
99
|
+
- `/tmp/praxis-layout-roundtrip-after-apply.json`: still identical to version 1.
|
|
100
|
+
- `/tmp/praxis-layout-roundtrip-saved.json`: version 2 with both column moves.
|
|
101
|
+
- `/tmp/praxis-layout-roundtrip-reloaded.json`: unchanged version 2.
|
|
102
|
+
- `/tmp/praxis-layout-roundtrip-original-after.json`: unchanged original version 92.
|
|
103
|
+
|
|
104
|
+
Runtime/editor assertions were based on rendered DOM, actual UI actions and
|
|
105
|
+
independent API reads. They do not establish which individual child storage
|
|
106
|
+
requests carried If-Match, enumerate all child config keys, or prove conflict
|
|
107
|
+
handling against deliberately older child preferences. The page version/ETag
|
|
108
|
+
change is confirmed; request-header conformance was not captured in this run.
|
|
109
|
+
|
|
110
|
+
No unit suite or production build was rerun for documentation-only changes. No
|
|
111
|
+
public API, generated manifest, public example, HTTP corpus or skill needed an
|
|
112
|
+
update: `praxis-form-editor-document-roundtrip` already distinguishes Apply,
|
|
113
|
+
component Save, page Save and rehydration. The finding adds concrete evidence,
|
|
114
|
+
not new platform guidance.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Layout toolbar: accessible editor preferences
|
|
2
|
+
|
|
3
|
+
Classification: `local-pequena`. Adherence:
|
|
4
|
+
`ja-suportado-mal-nomeado-ou-mal-materializado`. Dynamic Form already owns density
|
|
5
|
+
and border/separator editor state, Material toggles, CSS token bindings and an
|
|
6
|
+
i18n namespace. No missing contract justified a new input, configuration flag,
|
|
7
|
+
token or persisted setting.
|
|
8
|
+
|
|
9
|
+
The three density controls and two style controls previously had hardcoded
|
|
10
|
+
Portuguese tooltips but no accessible names on their native buttons. The style
|
|
11
|
+
group was also unnamed. The group labels did not distinguish editor preferences
|
|
12
|
+
from changes to the published form.
|
|
13
|
+
|
|
14
|
+
The fix adds translated accessible names to the Material inputs (not only their
|
|
15
|
+
hosts), translates both group labels and the toolbar name, and explains the
|
|
16
|
+
editor-only scope in tooltips. Visible groups are now **Densidade do editor** and
|
|
17
|
+
**Guias do editor**. `compact/cozy/regular` and `border/divider` retain their
|
|
18
|
+
existing state semantics. No CSS, icon source, token or document shape changed.
|
|
19
|
+
|
|
20
|
+
## Validation
|
|
21
|
+
|
|
22
|
+
- 38 tests passed across `layout-editor-toolbar.spec.ts` and
|
|
23
|
+
`layout-editor.component.spec.ts`. The new cases check native control names in
|
|
24
|
+
pt-BR/en-US, host translator override, selected/pressed states, and preference
|
|
25
|
+
changes without document mutation or configChange emission.
|
|
26
|
+
- The first test compile exposed a fixture translator return-type error; this
|
|
27
|
+
was corrected to use the existing typed host translator contract. Subsequent
|
|
28
|
+
initial-state assertions required a change-detection pass after asynchronous
|
|
29
|
+
ngModel stabilization. The final 38-test run passed.
|
|
30
|
+
- Browser on the official `/page-builder-ia` route, existing tab 8: opened the
|
|
31
|
+
selected employee's Form editor and Layout; verified all five accessible names;
|
|
32
|
+
used Space on Compacta, Bordas das seções and Separadores. States changed while
|
|
33
|
+
**Sem alterações**, disabled Apply and disabled Save remained intact. Restored
|
|
34
|
+
the initial preferences through the same UI.
|
|
35
|
+
- Screenshot review at viewport 1125×912, dark theme, expanded panel and reduced
|
|
36
|
+
panel (720px wide): group labels and controls wrap without overlap; the tooltip
|
|
37
|
+
explains editor-only behavior. This is reduced-panel coverage, not mobile or
|
|
38
|
+
full screen-reader certification. No light-theme screenshot or full AXE audit
|
|
39
|
+
was performed for this naming-only change.
|
|
40
|
+
|
|
41
|
+
Test log: `/tmp/praxis-layout-toolbar-tests-final.log`.
|
|
42
|
+
Build log: `/tmp/praxis-layout-toolbar-build.log`.
|
|
43
|
+
`npm run build:praxis-dynamic-form` completed successfully through the official
|
|
44
|
+
script's dependency/build closure. A final Config API GET confirmed page version
|
|
45
|
+
92, payload and ETag unchanged; receipt:
|
|
46
|
+
`/tmp/praxis-layout-toolbar-config-after.json`. No page or employee save was used.
|
|
47
|
+
|
|
48
|
+
The README now explains these existing preferences. Authoring manifests and
|
|
49
|
+
public APIs need no change: no authorable path, payload or operation changed.
|
|
50
|
+
Public-site examples, HTTP corpus and generated catalogs do not expose a new
|
|
51
|
+
contract to synchronize. Existing layout/design skills already require named
|
|
52
|
+
icon controls, i18n, host overrides and preservation of drafts; no skill change
|
|
53
|
+
or installation sync is needed for this correction.
|
|
54
|
+
|
|
55
|
+
Other hardcoded copy, the global gap control and broader layout composition
|
|
56
|
+
remain outside this focused fix. This does not certify the whole editor as
|
|
57
|
+
localized or redesign its information architecture.
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# Master-detail customization: controlled comparison
|
|
2
|
+
|
|
3
|
+
## Scope
|
|
4
|
+
|
|
5
|
+
Classification: `local-pequena` tests and documentation. Existing widget inputs,
|
|
6
|
+
composition links, authoring document and capabilities represent every scenario;
|
|
7
|
+
no new contract or runtime patch is justified by these results.
|
|
8
|
+
|
|
9
|
+
The reported failure remains open on `/page-builder-ia`. This matrix progressively
|
|
10
|
+
adds factors from that page to the previously passing minimal composition, using
|
|
11
|
+
real Table, Form, widget loader and Page Builder components with controlled HTTP.
|
|
12
|
+
|
|
13
|
+
## Final result
|
|
14
|
+
|
|
15
|
+
All **8 scenarios passed** in ChromeHeadless:
|
|
16
|
+
|
|
17
|
+
| Scenario | Added factor | Result |
|
|
18
|
+
| --- | --- | --- |
|
|
19
|
+
| 1 | Direct composition runtime with child customization | Pass |
|
|
20
|
+
| 2 | Page Builder host | Pass |
|
|
21
|
+
| 3 | Saved form layout and metadata: 18 fields, 4 sections | Pass |
|
|
22
|
+
| 4 | Builder agentic control enabled | Pass |
|
|
23
|
+
| 5 | Form AI control also enabled | Pass |
|
|
24
|
+
| 6 | Authoring document plus host `pageChange` acknowledgement | Pass |
|
|
25
|
+
| 7 | Saved identity links, transient state, detail shell and canvas | Pass |
|
|
26
|
+
| 8 | Resource schema discovery/reconciliation with `input-first` layout | Pass |
|
|
27
|
+
|
|
28
|
+
Each scenario uses two fictional employees with populated names, dates, monetary
|
|
29
|
+
values, booleans and job/department references. It clicks real table rows and
|
|
30
|
+
checks both child customization inputs, the selected entity, displayed name,
|
|
31
|
+
view/presentation mode, stable loaded component instances during mode changes,
|
|
32
|
+
unchanged authored page JSON and no page/FormConfig saves. It also leaves editing
|
|
33
|
+
while the second entity read is pending and hovers/selects a form section before
|
|
34
|
+
leaving editing. Section selection is cleared on exit.
|
|
35
|
+
|
|
36
|
+
The reference fields issue canonical `jobRole` and `department` option-source
|
|
37
|
+
`options/by-ids` GETs. The test answers these with matching IDs/labels, ignores
|
|
38
|
+
already-cancelled requests and requires settling within a bounded number of
|
|
39
|
+
response rounds. Earlier name-only responses did not exercise these lookups and
|
|
40
|
+
were insufficient to represent a populated employee detail.
|
|
41
|
+
|
|
42
|
+
Log: `/tmp/praxis-master-detail-schema-boundary.log`. The final eight scenarios
|
|
43
|
+
completed successfully (1.906 seconds of test execution). No full
|
|
44
|
+
workspace suite, production build or live LLM request was run. Enabling AI
|
|
45
|
+
controls does not certify backend AI authoring or session transport.
|
|
46
|
+
|
|
47
|
+
## Fixture provenance and limits
|
|
48
|
+
|
|
49
|
+
`src/lib/test-fixtures/page-builder-employee-form.config.json` takes layout,
|
|
50
|
+
field metadata and editorial block configuration from the version-92 reference
|
|
51
|
+
document. It excludes schema hash/context/verification timestamp and records.
|
|
52
|
+
`page-builder-employee-framing.json` takes its state, five composition links,
|
|
53
|
+
canvas/layout and detail shell; widget keys are mapped to the fixture's `people`
|
|
54
|
+
and `detail`, and the unrelated page-header widget is excluded.
|
|
55
|
+
|
|
56
|
+
These fixtures are test inputs, not new public presets or a second metadata
|
|
57
|
+
source. They intentionally retain field configuration details that a simplified
|
|
58
|
+
handwritten form would omit. Responses are fictional; avatars remain null.
|
|
59
|
+
|
|
60
|
+
`page-builder-employee-response.schema.json` is the response read on September 8
|
|
61
|
+
from the reference API's `/schemas/filtered` for
|
|
62
|
+
`path=/api/human-resources/funcionarios/all&operation=get&schemaType=response`.
|
|
63
|
+
It contains schema metadata and documentation examples, not queried employee
|
|
64
|
+
records. Scenario 8 uses the real SchemaMetadataClient and normalizer, with only
|
|
65
|
+
the `fetch` transport intercepted. Responses use a synthetic ETag and return 304
|
|
66
|
+
when that tag is supplied. The test asserts successful initialization, retained
|
|
67
|
+
authored section IDs, the schema hash, no false outdated warning, and no further
|
|
68
|
+
schema reads during three additional settling turns after the interactions.
|
|
69
|
+
|
|
70
|
+
Initial failures in this extension concerned overly broad persistence assertions,
|
|
71
|
+
not hydration or a reproduced browser crash. The runtime separately persists
|
|
72
|
+
`form-schema-meta:*` evidence/index and `conn:form:*` connection identity with
|
|
73
|
+
`origin: input`. The final assertion checks those keys and payload shapes while
|
|
74
|
+
rejecting page/FormConfig saves. `input-first` and page `autoPersist=false` do not
|
|
75
|
+
mean that every child storage write is disabled. This is observed existing
|
|
76
|
+
behavior, not a new persistence contract. Storage reads still return null in this
|
|
77
|
+
fixture; persisted-child conflict/roundtrip behavior is outside this proof.
|
|
78
|
+
|
|
79
|
+
This matrix does **not** reproduce the full saved-page host: real network timing,
|
|
80
|
+
persisted child configuration loading, the remote table, the app's
|
|
81
|
+
global providers/interceptors/theme, and actual pointer movement
|
|
82
|
+
remain differences. Mouse events in a DOM test cover handlers, not full browser
|
|
83
|
+
hit testing. No factor can be excluded as a cause under every combination merely
|
|
84
|
+
because the controlled scenario passes.
|
|
85
|
+
|
|
86
|
+
## Earlier browser failure
|
|
87
|
+
|
|
88
|
+
The previously responsive reference tab navigated to `/page-builder-ia` and
|
|
89
|
+
loaded its table. Selecting Ayla and waiting for her name in the detail region
|
|
90
|
+
completed; the next request to access the app switch for keyboard interaction
|
|
91
|
+
timed out in `Runtime.evaluate`. The switch transition was not confirmed. This
|
|
92
|
+
does not establish editing as the exclusive trigger: failure may occur after
|
|
93
|
+
detail hydration, before the next interaction can be performed.
|
|
94
|
+
|
|
95
|
+
Old crashed tabs could not be cleaned up through the browser tool: attempting to
|
|
96
|
+
obtain a crashed tab was blocked by its URL policy for the generated crash page.
|
|
97
|
+
No bypass was attempted and clean browser-process recovery is not claimed.
|
|
98
|
+
|
|
99
|
+
Read-only GET after the comparison returned version 92, structurally identical
|
|
100
|
+
to `/tmp/praxis-draft-rollout-final.json`. The saved page was not modified.
|
|
101
|
+
|
|
102
|
+
## Follow-up browser journey and next gate
|
|
103
|
+
|
|
104
|
+
The schema gate above is now covered by scenario 8. A fresh inventory confirmed
|
|
105
|
+
four previously failed tabs and one responsive existing tab (8). No new tab was
|
|
106
|
+
opened. In that tab, the following actual UI journey completed:
|
|
107
|
+
|
|
108
|
+
1. Leave page editing, select reference record 235 and wait for its detail.
|
|
109
|
+
2. Enable editing and confirm the checked switch in a subsequent snapshot.
|
|
110
|
+
3. Leave editing, select record 193 (Ayla, also used in the earlier failure),
|
|
111
|
+
wait for detail and confirm that another DOM read succeeds.
|
|
112
|
+
4. Enable editing, open **Configurar formulário**, and confirm **Visualizar**
|
|
113
|
+
plus **Apresentação** selected in General settings.
|
|
114
|
+
5. Open **Layout**, inspect its populated sections/fields, cancel without
|
|
115
|
+
changes, and leave editing. Confirm no dialog, an unchecked switch and the
|
|
116
|
+
detail region still present. The tab was left available for visual review.
|
|
117
|
+
|
|
118
|
+
The final read-only configuration GET again matched version 92 exactly. This
|
|
119
|
+
journey did not save a page, edit employee data or modify a layout draft. It
|
|
120
|
+
proves successful interaction in this run; it does not explain previous crashed
|
|
121
|
+
tabs or establish lasting stability. The readonly resolved-runtime panel also
|
|
122
|
+
displayed `legacy CRUD fallback`; that label alone is not evidence that the
|
|
123
|
+
actual schema request fell back and should be checked against transport evidence
|
|
124
|
+
before being used diagnostically.
|
|
125
|
+
|
|
126
|
+
## Layout edit and cancellation proof
|
|
127
|
+
|
|
128
|
+
The next interactive gate also passed on September 8 in existing tab 8.
|
|
129
|
+
Classification of this follow-up: `docs-apenas`; no production code or test code
|
|
130
|
+
changed. The behavior is `ja-suportado-so-ux`: column movement, draft tracking,
|
|
131
|
+
discard confirmation and the data/presentation modes already have canonical
|
|
132
|
+
implementations. No additional contract was required.
|
|
133
|
+
|
|
134
|
+
Starting with record 193 selected and page editing off, the journey captured the
|
|
135
|
+
detail region's text and the Layout tab's text as comparison baselines. It then:
|
|
136
|
+
|
|
137
|
+
1. Enabled page editing and opened **Configurar formulário → Layout**.
|
|
138
|
+
2. Opened **Seção 1 → Linha 2 → Coluna 1 → Opções da coluna** and selected
|
|
139
|
+
**Mover para direita**. The draft then showed CPF before Nome Completo,
|
|
140
|
+
with both columns still at 6/12. Apply and Save became enabled.
|
|
141
|
+
3. Clicked **Cancelar**. The **Descartar rascunho não salvo** dialog appeared.
|
|
142
|
+
Choosing **Continuar editando** retained the changed field order.
|
|
143
|
+
4. Cancelled again and chose **Descartar rascunho**. Reopened the same editor:
|
|
144
|
+
the complete Layout tab text matched its initial baseline, including field
|
|
145
|
+
ordering. General settings showed **Sem alterações**, **Visualizar** and
|
|
146
|
+
**Apresentação** selected; the table still had record 193 selected.
|
|
147
|
+
5. Closed the unchanged editor and left editing. The complete detail-region text
|
|
148
|
+
matched its initial baseline, including the displayed values and their order.
|
|
149
|
+
The responsive tab was left in consultation mode for user review.
|
|
150
|
+
|
|
151
|
+
Read-only page configuration GETs before and after were structurally identical,
|
|
152
|
+
both at version 92 (`/tmp/praxis-layout-cancel-before.json` and
|
|
153
|
+
`/tmp/praxis-layout-cancel-after.json`). No Apply, Save or employee command was
|
|
154
|
+
used. These comparisons establish cancellation behavior for a menu-based column
|
|
155
|
+
move. They do not cover drag hit testing, discard after Apply, browser reload,
|
|
156
|
+
remote save/reopen, or every child storage key. The earlier eight automated
|
|
157
|
+
scenarios were not rerun for this documentation-only follow-up.
|
|
158
|
+
|
|
159
|
+
UX observation: the discard dialog explains that an already-applied preview is
|
|
160
|
+
retained, even in this journey where Apply was never used. That wording describes
|
|
161
|
+
the general behavior but introduces an unused state into the decision. If refined,
|
|
162
|
+
it should derive from the editor's existing applied/draft state and translation
|
|
163
|
+
resources; this run does not justify a new configuration flag or contract.
|
|
164
|
+
|
|
165
|
+
The isolated Apply/Save/reopen gate subsequently completed; see
|
|
166
|
+
[the operational proof](./layout-apply-save-reopen-2026-09-08.md). It confirms both
|
|
167
|
+
column moves, modes and page versioning, while recording a separate pointer
|
|
168
|
+
selection inconsistency after reload. That radio behavior was subsequently
|
|
169
|
+
isolated and corrected; see
|
|
170
|
+
[the Table selection proof](../../praxis-table/test-dev/radio-pointer-selection-2026-09-08.md).
|
|
171
|
+
The eight integration scenarios passed again, with the resource-schema scenario
|
|
172
|
+
now activating Material's touch target. The retained copy also passed live
|
|
173
|
+
pointer/keyboard/row selection after correcting an undeclared Rich Content input
|
|
174
|
+
introduced during fixture preparation. The original version 92 remained intact.
|
|
175
|
+
The remaining broader gate is the complete Page Builder host journey; the lab
|
|
176
|
+
proof does not certify that host or explain earlier browser crashes. Capture any
|
|
177
|
+
recurring failure before changing runtime, without removing customization, draft
|
|
178
|
+
preservation or field configuration to mask it.
|
|
179
|
+
|
|
180
|
+
No public API, generated manifest, HTTP corpus or installed skill changed.
|
|
181
|
+
Existing skills already require canonical sources and exact coverage statements;
|
|
182
|
+
this investigation adds evidence rather than a new runtime rule.
|