Visão em tabela (OmniDataGrid) + painel de detalhes à direita ou abaixo - #7
Merged
Merged
Conversation
O detalhe so abria a direita. Um botao na toolbar passa a alternar entre a direita e abaixo: a direita funciona melhor em telas largas, abaixo e melhor para stack traces longos e telas estreitas. O icone aponta para ONDE o painel vai (seta para baixo / para a direita), e nao onde ele esta — a lib nao tem icones de painel, e a seta remove a ambiguidade. O botao so aparece quando ha um detalhe aberto para reposicionar. O splitter recebe @key na orientacao: ele mede e fixa os tamanhos dos panes na inicializacao, entao reaproveitar a instancia deixaria as larguras da disposicao anterior aplicadas na nova. A preferencia e persistida em ui.json — e nao no settings.json de proposito: o SettingsService dispara Changed ao salvar e o LogStore reage recarregando todos os arquivos, o que seria absurdo para uma preferencia visual. O enum e gravado por nome (Bottom), ja que o arquivo e editavel a mao. Validado no app: alterna nos dois sentidos e a escolha sobrevive a reabertura. 6 testes novos, incluindo arquivo corrompido e valor desconhecido caindo no padrao. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
There was a problem hiding this comment.
Pull request overview
Este PR adiciona uma preferência de UI persistida para alternar a posição do painel de detalhes no LogViewer entre à direita e abaixo da lista, escolhendo a disposição mais adequada conforme o tamanho da tela e o tamanho do stack trace. A persistência é feita em ui.json via um novo serviço dedicado, evitando impactos colaterais do SettingsService (como recarregamento de logs).
Changes:
- Cria
UiPreferencesServicepara carregar/salvar preferências visuais emui.json(com enum serializado por nome). - Introduz o enum
DetailPanelPositione integra a orientação do splitter noLogViewer(com@keypara recriar na troca). - Adiciona um botão (condicional) na
LogToolbarpara alternar a posição do painel, e adiciona testes cobrindo default, alternância e persistência.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| test/ClefExplorer.Tests/UiPreferencesTests.cs | Testa default, alternância, persistência e tolerância a ui.json inválido/desconhecido. |
| src/Services/UiPreferencesService.cs | Implementa carregamento/salvamento de ui.json com enum em string e fallback seguro. |
| src/Program.cs | Registra UiPreferencesService no DI container. |
| src/Models/DetailPanelPosition.cs | Define o enum persistido (Right/Bottom) com documentação. |
| src/Components/LogViewer.razor | Alterna orientação do OmniSplitter com base na preferência e persiste via serviço. |
| src/Components/LogToolbar.razor | Inclui botão (apenas com detalhe aberto) para alternar a posição do painel. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Alem da lista, um botao na toolbar alterna para uma tabela com ordenacao, agrupamento (arrastando a coluna para a faixa acima), filtro por coluna e redimensionamento. A escolha e persistida. Colunas derivadas do CONTEUDO: logs CLEF carregam propriedades estruturadas que variam conforme a aplicacao que os gerou, entao fixa-las na mao nao funcionaria. O LogColumnDiscovery amostra os eventos carregados, conta a frequencia de cada propriedade e oferece como coluna as que aparecem o suficiente, com o nome ja legivel - "MachineName" vira "Machine Name". O desempate por nome mantem a ordem estavel entre aberturas. O seletor de colunas e proprio, e nao o embutido (AllowColumnVisibility=false). Motivo: a coluna aplica a visibilidade no proprio OnInitialized, entao toda vez que o grid e recriado - o que acontece ao abrir/fechar o detalhe, ja que o layout troca de splitter - as escolhas do menu interno se perdiam. Mantendo o conjunto do lado do app, ele sobrevive a recriacao e ainda persiste entre execucoes. Tentei estabilizar a arvore mantendo o splitter sempre montado com o pane do detalhe colapsado, mas isso reintroduz a race de medicao do splitter aninhado (o conteudo mede 0px e some). Por isso a renderizacao condicional foi mantida e o problema foi resolvido pelo lado do estado. 19 testes novos: descoberta (frequencia, corte de raras, exclusao das que ja tem coluna fixa, teto, estabilidade, amostragem), rotulo legivel e valor da celula (sem as aspas que o ScalarValue adiciona). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Com 'pull_request: branches: [main]', PRs empilhados — que apontam para outra branch de feature — ficavam sem CI: aconteceu no #5 e no #7, onde o gate de testes so passou a valer depois de disparar o workflow na mao. Removido o filtro de base; o gatilho de push continua restrito a main. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A versao vivia solta no csproj e ficou em 1.0.0 enquanto a Store ja estava em 1.0.2 — o titulo da janela, que le a versao do assembly, mostrava um numero diferente do publicado. Directory.Build.props passa a ser a fonte unica: - o csproj herda Version/FileVersion/AssemblyVersion (verificado: o assembly agora sai 1.1.0.0); - publish-store-package.ps1 usa esse valor quando -Version nao e informado; - release.yml passa /p:Version com a versao da tag, entao o exe dentro do pacote carrega a mesma versao carimbada no manifesto — antes o manifesto ia com a versao da tag e o assembly ficava em 1.0.0. Higiene: - o tipo de arquivo registrado virou 'Clef Log File'; 'Reader Log File' era sobra de copy/paste e divergia do rotulo do Package.appxmanifest; - RuntimeIdentifiers fica so em win-x64: e o que o CI publica, o que o pacote da Store contem e o que o README anuncia. Declarar win-x86 sugeria um suporte que nao existe. Nao suprimi o aviso MSB3277 remanescente: ele vem da unificacao de WindowsBase pelo proprio pacote WebView2 e mascarar conflitos de assembly com NoWarn e pior do que conviver com o ruido. Os avisos CS do nosso codigo seguem zerados. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A lista montava um no no DOM por evento da pagina. O roadmap pedia para medir antes: com paginas de ate 100 a virtualizacao renderia pouco, entao o ganho de verdade vinha junto com paginas maiores. A lista passa a usar OmniVirtualize (Height=null: o pai ja limita a altura e faz o scroll; sem altura limitada o Virtualize renderiza tudo) e o seletor ganha 250/500/1000 itens por pagina. Verificado com 5000 eventos: pagina de 1000 rola sem travar. Correcao encontrada durante esse teste: OmniPagination e zero-based e o app conta a partir de 1 — que e o numero mostrado no "X-Y de Z". Sem conversao, a pagina 1 aparecia como "2 / 100" e a ultima pagina ficava inalcancavel, porque o clamp do app ia ate UltimaPagina enquanto o componente esperava UltimaPagina - 1. A traducao ficou na fronteira, dentro da LogToolbar. Bug meu, introduzido na migracao do P2 ao trocar os botoes manuais pelo componente. Verificado: "1-50 de 5000" com "1 / 100", e o proximo leva a "51-100" / "2 / 100". Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Nao houve passe de a11y depois da migracao. Os componentes da Omni ja vem tratados, mas os elementos clef-* proprios nao. Lista de eventos: era uma pilha de div com @OnClick - nao recebia foco, nao respondia ao teclado e o leitor de tela nao a anunciava como lista selecionavel. Agora e role=listbox com itens role=option, tabindex e aria-selected, ativaveis por Enter/Espaco. Cada item ganhou um aria-label montado com nivel, hora, mensagem e a marca de excecao: sem ele o item seria lido como textos soltos e o nivel, que visualmente e um badge colorido, se perderia. Itens de grupo viraram button de verdade em vez de div com @OnClick - foco, teclado e semantica de graca. Nao ha nada interativo aninhado, entao a troca e segura; o CSS ganhou o reset de aparencia correspondente. Indicador de foco: nenhum elemento clef-* tinha. Adicionado via :focus-visible, que mostra o anel so na navegacao por teclado, sem poluir o clique de mouse. O contraste ja tinha sido tratado na migracao (WCAG AA medido no DOM nos dois temas), entao ficou de fora deste passe. Nao consegui confirmar o anel de foco na tela: a maquina bloqueou durante o teste. As mudancas sao estruturais e compilam, mas a verificacao visual fica pendente. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Roadmap P4: virtualização, acessibilidade, versionamento e higiene (+ bug de paginação)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resumo
O painel de detalhes só abria à direita. Agora um botão na toolbar alterna entre à direita e abaixo da lista — à direita funciona melhor em telas largas; abaixo, para stack traces longos e telas estreitas.
Como ficou
↓/→), não onde ele está — a Omni não tem ícones de painel, e a seta remove a ambiguidadeDuas decisões que valem explicação
1. A preferência vai em
ui.json, não emsettings.json. OSettingsServicedisparaChangedao salvar, e oLogStorereage a esse evento recarregando todos os arquivos de log. Uma preferência puramente visual não pode custar isso. O enum é gravado por nome ("Bottom") porque o arquivo é editável à mão —1não diria nada.2. O splitter recebe
@keyna orientação. Ele mede e fixa os tamanhos dos panes na inicialização; reaproveitar a instância deixaria as larguras da disposição anterior aplicadas na nova. O@keyforça a recriação na troca.Verificação
ui.jsoncom"DetailPanelPosition": "Bottom").🤖 Generated with Claude Code