vtex / shoreline

VTEX Design System for back-office experiences. Currently available for internal usage at VTEX.
https://shoreline.vtex.com
24 stars 1 forks source link

Bulk action bar for Collection #1766

Closed malu-viana closed 3 months ago

malu-viana commented 4 months ago

Problem

No momento temos o componente de Table no Shoreline e, apesar de já ter a variação de linhas selecionáveis, ainda não temos o componente para habilitar as ações em massa. Temos em diversos produtos (Logistics, Marketplace In/Out e Identity mapeados até então) a necessidade de aplicar ações em massa, atualmente utilizando a Table do Admin UI, que possui este componente.

Entendendo que existem casos de uso para este componente em múltiplos times, um desafio também é resolver os problemas de usabilidade contidos no componente do Admin UI, como:

Solution

Branch do componente no Figma

Usage examples

137 125 128 135

Dependencies

No response

References

Principais referências

Outras referências Ref 01 Ref 02 Ref 03
image 6 image 5 image 1
renatamottam commented 4 months ago

Legal, Malu! Fiquei com algumas dúvidas:

  1. O que teria que se criar de fato? Pelo que entendi, seria:
    • um botão de bulk actions dentro da TableHeader que apareceria quando algo fosse selecionado
    • alerta de erro/sucesso após ação (imagino que usaríamos uma Toast mas seria bom registrar isso pra engenharia)
  2. Como ficaria a lista com nada selecionado? Esse botão vai de fato só aparecer quando você seleciona algo?
  3. Não entendi porque tem o "Selecionar todos" e o checkbox que faz isso. Precisa dos dois?
malu-viana commented 4 months ago

@renatamottam

  1. Sim para o primeiro ponto. E os feedbacks das ações executadas por este meio seguiriam o mesmo padrão da single action definida no design do produto (toast é o padrão)
  2. Isso! A partir da seleção de algum item na listagem, a primeira coluna do TableHeader seria substituída pelo componente de BulkActions
  3. O CTA Selecionar todos seleciona todos os itens da listagem, não só da página (opcional o uso no design)
lafray commented 4 months ago

Eu tenho alguns pontos que acho que podem contribuir para a discussão.

  1. A substituição parcial do header não pode virar um problema? No exemplo que você trouxe as imagens, o width da primeira coluna (sem contar a coluna de seleção) é grande, mas esse é sempre o caso? Por que se formos lidar com cenários em que essa coluna tem um width menor, podemos ter um problema de falta de espaço ou sobreposição de elementos. Vejo que em mobile talvez seja um problema tambem pela mesa questão.

  2. Sobre o label do selecionar todos, acho que seria importante ser mais explicito que é de todas as paginas. Pela minha experiencia com o bulkaction do Admin-ui, esse label já causava mals entendidos sobre o que é "todos". Talvez "Selecionar todas as paginas" ou "Selecionar em todas as paginas"

  3. Esse ponto é um pouco mais filosofico, mas acho que pode ser relavante. Estava olhando as referências que trouxe, e fi que uma delas não subistitui o header masi sim colocar uma "linha" a cima (ref 1). Ai fiquei pensando se esse caminho não seria mais interessante por ser mais fácil de lidar com o pontos que trouxe em "1". E pensando nisso olhei a referencia 2, em que não é nem em uma tabela exatamente, e sim uma listagem (pelo que entendi do recorte da imagem). E me perguntei que se formos nesse caminho de não ser o header, mas sim uma "linha a cima", não resolveriamos mais cenários mantendo uma consistencia de design?

  4. Queria entender também a motivação da contagem ficar no label do botão. Acho que essa escolhar pode trazer algums problemas:

    • Se formos por algo assim, acho que a definição do label acabaria ficando a cargo de quem usa, pois podem ter casos em que a ação não seja de edição, por exemplo. E dai mostrar a contagem também ficaria a cargo do usuário do componente. Vejo que rápidamente teram pessoas mostrando essa contagem de formas diferentes, e perderiamos em consistencia do design em diferentes apps.
    • Semanticamente me parece estranho juntar num único elemento "o que"(ação) com "no que" (sob o que se aplica a ação). Normalmente quando precisamos dessas duas informações elas vem e elementos diferentes. Veja um modal de confirmação por exemplo, seu botão tem o label "confirmar" e não "confirmar item A" e o item ta em outro elemento, o titulo do modal, por exemplo.
    • Talvez seja só uma sensação minha. Mas me parece muito estranho um botão que o label fica mudando conforme vou selecionado e deselecionando elementos.
malu-viana commented 4 months ago

@lafray

  1. Todos os casos de uso de bulk action que analisei possuem um width da primeira coluna maior do que a barra para ações em massa seria. Acredito que para esse edge case, dessa largura da primeira coluna ser menor, podemos ir pelo caminho de setar uma min-width nos casos de ativas bulk actions na table.

  2. Concordo com esse ponto. Pensei como reforço para a seleção da lista completa dois caminhos: Usar o contador de itens total (Selecionar todos X) ou mudar esse copy (Selecionar toda lista)

  3. Esse caminho foi explorado, mas causa um layout shift na listagem pela adição do componente. E como a substituição deste no header é somente da primeira coluna, que por ser a principal informação da tabela não apresenta um problema o título ser ocultado momentaneamente, acabei entendendo que o ganho aqui seria maior.

  4. Acho que a label deste botão deve ser fixa, o que seria editável seriam as ações no dropdown (quanto ao "editar", podemos estressar esse copy também pra deixar mais claro que são ações sob aqueles itens selecionados, ou alinhar que o editar faz sentido para contemplar quaisquer ações). Quanto ao botão com cotador e a ação indicar isso, é uma prática bem comum mesmo que não tenhamos casos de uso na VTEX seguindo esse padrão. Acho que quanto ao copy disso, vale o input de Localization também pra chegar nessa conclusão, principalmente no CTA de menu.

dinizo-v2 commented 4 months ago
Screenshot 2024-07-30 at 12 03 41

Um exemplo que gosto bastante de diferenciação de selecionar todos é do gmail.

malu-viana commented 4 months ago
Screenshot 2024-07-30 at 12 03 41

Um exemplo que gosto bastante de diferenciação de selecionar todos é do gmail.

Também gosto bastante! Acho que um ponto nesse caso do Gmail é o uso do espaço com o copy né... Será que seguindo com a adição do contador já seria suficiente? "Select all 497" ou "Select all 497 items". Outro comportamento que gosto é de aparecer o "Select all" somente quando toda a página já está selecionada.

lafray commented 4 months ago

Uma pergunta sobre o comportamento do selecionar todos. Como fica a interação se depois dele clicar em selecionar tudo ele interagir com os seletores das linha, deselecionando itens?

malu-viana commented 4 months ago

@lafray Acho este um ótimo ponto pra ter a perspectiva de engenharia, por questões técnicas tb! No gmail por exemplo, caso a lista completa esteja selecionada e um item na página for selecionado, volta a se tratar da seleção na página

davicostalf commented 4 months ago

@malu-viana Esse ícone de três pontinhos no Menu o padrão é só usar ele quando o label é "More actions". O componente de Menu no Figma tem uma prop type, e nesse caso acho que o valor dela deveria ser "custom label".


Outro comportamento que gosto é de aparecer o "Select all" somente quando toda a página já está selecionada.

Achei interessante isso também. Pode ser uma boa. Testaria como label "Select all pages"


Como fica a interação se depois dele clicar em selecionar tudo ele interagir com os seletores das linha, deselecionando itens?

Temos até um comentário na documentação do Bulk Actions no Admin UI sobre esse cenário. Tem muito a ver com limitações de API. Acho que o componente dessa vez deveria ser desenvolvido considerando os dois cenários:

What should happen when the Select All button is clicked? When the Select All action is triggered, all the items of all pages are selected. After the selection, the possibility of unselecting specific items depends on the API of the involved system. The ideal behavior is that the merchant can click on the Checkbox of specific selected items to unselect them. However, the API might not support registering all the items. In this case, when clicking Select All, the Checkbox of all items must be selected and disabled. It should only be enabled when the merchant clicks Deselect All.


@matheusps Fiquei curioso pra escutar sua opinião, considerando que você tinha muitas críticas sobre o componente anterior.

beatrizmilhomem commented 4 months ago
image
malu-viana commented 4 months ago

@beatrizmilhomem Gosto dessa referência do Github também! Tá bem alinhada com a proposta. Sobre os dois primeiros pontos: concordo! Me diz o que tu acha dessa iteração?

Group Management

Page

matheusps commented 4 months ago

A minha primeira reação à essa interação está no ponto 1 do @lafray:

A substituição parcial do header não pode virar um problema? No exemplo que você trouxe as imagens, o width da primeira coluna (sem contar a coluna de seleção) é grande, mas esse é sempre o caso? Por que se formos lidar com cenários em que essa coluna tem um width menor, podemos ter um problema de falta de espaço ou sobreposição de elementos. Vejo que em mobile talvez seja um problema tambem pela mesa questão.

Acredito que o header deveria ser substituído pro completo para resolver essa provável inconsistência. Isso também deixaria mais espaço para novas ações importantes que não estivessem contidas em um menu, como acontece no Gmail. E sobre essa resposta:

Todos os casos de uso de bulk action que analisei possuem um width da primeira coluna maior do que a barra para ações em massa seria...

Acho que temos pouco material dado a jovem idade do design system. Acho que uma substituição completa seria mais robusta para o futuro.

Sobre a resposta do ponto 3.

Esse caminho foi explorado, mas causa um layout shift na listagem pela adição do componente

Não causaria um layout shift se juntássemos o conceito de filtragem bulk actions em uma mesma barra, como no Gmail. Claro, isso envolveria um redesign de como vemos filtros - mas é uma interação possível sem um shift.


Completando, gosto do caminho - eu apenas faria uma substituição completa no header, ao invés de uma parcial.

beatrizmilhomem commented 4 months ago

Me diz o que tu acha dessa iteração?

@malu-viana Tá ficando ótimo! ✨ Como ficaria no scroll com o header fixo? Outra coisa, chegou a testar sem o stroke no topo e laterais? Se quiser, compartilha o link onde vc tá fazendo as explorações tb. :)

Completando, gosto do caminho - eu apenas faria uma substituição completa no header, ao invés de uma parcial.

Concordo com @matheusps , até olhando pra essa última iteração, manter as labels ali da direita fica até meio confuso. Substituindo todo o header vai acabar dando mais clareza pro comportamento de bulk actions, dá mais espaço pra possíveis outras ações e fica mais escalável pra telas menores.

malu-viana commented 4 months ago

@beatrizmilhomem @matheusps

Substituir o header da Table me preocupa pelo usuário perder a referência das informações abaixo. Vamos imaginar num cenário onde existem múltiplas colunas retratando números, sem o header da Table essa falta de referência pode gerar um problema. No caso do Gmail funciona muito bem pois o header da lista já é o local de ações por default.

Um caminho que pode funcionar, para nem perder a referência das colunas e nem ter essa quebra, é termos uma barra de ações fixa no caso de ações em massa estar ativa no componente de Table.

Page Page-1 Page-2

matheusps commented 4 months ago

Esse tá bem melhor @malu-viana

beatrizmilhomem commented 4 months ago

Tô achando muito bom esse caminho :sparkles::sparkles::sparkles:

Tava pensando agora que tá ficando com 3 linhas de elementos acima da tabela e vc até já tá trazendo um botão de export pra essa nova barra que antes ficaria ali do lado da paginação. Aí assim, se todas as ações ficarem nessa nova barra, será que daria pra otimizar o espaço de filtros e paginação, pra ficar só com 2 linhas antes da tabela? Mexeria no padrão do Collection, mas acho que é um teste válido 🤔 eu tb achei legal a ref do Notion, que a barra aparece flutuando, pode ser uma saída tb pra não ser mais 1 linha fixa!

image image

BeatrizAlbino commented 4 months ago

Esse componente é uma necessidade em Payments também! No passado eu precisei fazer uma migração de tela de listagem para o Admin UI e usei uma bulk actions bar para fazer inativação de regras em massa, mas a tela não foi implementada. Lembro que usei de referência o do Google Drive na época, hoje em dia ele mudou mas continuo achando legal a barra de cima, só acho pouco intuitivo a seleção de múltiplos itens sem checkbox.

Google Drive (atualmente):

image

Projeto de Payment Rules (2021): image

malu-viana commented 4 months ago

Eu gosto muito desse bench do Notion com a floating bar! Acho que contempla os requisitos que trouxemos aqui na discussão:

@beatrizmilhomem @matheusps @lafray @davicostalf o que acham desse caminho?

Page Page-2 Page-1 Page-4 Page3 Page5
lafray commented 4 months ago

Eu particularmente achava mais interessante a interação anterior com a linha fixa. Tenho algumas inquietudes com esse camanhi da barra flutuante.

  • Não ocultar nenhuma informação existente

Não oculta permanentemente, mas o usuário tem que ficar trocando ela de lugar para conseguir enxergar o que esta embaixo. Eu costumo odiar telas com esse tipo de interação quando.

Mas o ponto que mais me preocupa é acessibilidade.

A navegação por teclado fica prejudicada. Você não consegue fazer uma navegação por teclado intuitiva para mudar o componente de lugar para enxergar o que esta embaixo. O usuário tera que ficar recorrendo ao mouse para mudar a posição do elemento. Leitor de tela não sei se não fica prejudicado também

davicostalf commented 4 months ago

Já passamos por algumas soluções:

  1. Barra flutuante fixa (como era no Admin UI)
  2. Barra flutuante reposicionável
  3. Menu com ações substituindo label da primeira coluna da tabela
  4. Barra que substitui header da tabela e esconde o label de todas as colunas
  5. Barra entre os filtros e o table header, visível até quando não há seleção
  6. Barra entre os filtros e o table header, que aparece após seleção

Todas as opções tem seus prós e contras. Até agora minhas favoritas são a 3 e a 6. Tem também outra opção que eu acho interessante, que é mostrar as ações contextuais no lugar onde já ficam normalmente as ações no Collection: image

matheusps commented 3 months ago

Para mim, a opção 4 é a melhor pois:

  1. É intuitiva em termos de UX - diferente das opções 1, 2, 5, 6.
  2. Escalável em diferentes tamanhos de tela, tabela, e quantidade de ações - diferente das opções 3, 5 e 6.
  3. Tem uma implementação pouco problemática - diferente da opção 2.
BeatrizAlbino commented 3 months ago

Gostei bastante da 6! Não esconde as labels das colunas e também não fica fixo na UI default

malu-viana commented 3 months ago

@matheusps @BeatrizAlbino @davicostalf @renatamottam @beatrizmilhomem @lafray

Obrigada por todos os pontos! Acho que os tradeoffs de cada caminho já estão bem delineados. Com tudo que foi dito, a opção 6 carrega o menor dos problemas levantados: o layout shift. Acho que o próximo passo agora é alinhar a interação no momento de seleção do primeiro item, para tentar mitigar esse problema.

Quanto a opção 2, levantada por @matheusps, ocultar o header da tabela vai contra algumas heurísticas de usabilidade, podendo trazer um sério problema de UX pro usuário, nos casos de uma listagem mais complexa (múltiplas colunas exibindo dados numéricos, por exemplo), ao perder a referência do que seriam os valores listados.

Gravei um vídeo da opção 6 iterada, vejo como uma opção escalável, com affordance pro usuário e sem conflitos de acessibilidade e responsividade de tela.

https://github.com/user-attachments/assets/6c3733a0-0ffd-42a6-913d-652824b62460

@davicostalf Explorei bastante o caminho das ações ao lado da paginação, é uma opção bem interessante também, mas vejo sendo menos escalável por questões de hierarquia e espaço. Posso te mostrar o que explorei se quiser :)

matheusps commented 3 months ago

@malu-viana, meu principal problema com essa solução é o Layout Shift. Inclusive, esse problema já foi apontado na tabela que tínhamos no Styleguide.

lafray commented 3 months ago

@malu-viana e @matheusps, você acreditão que o espaço que a solução 5 ocupa é tão grave assim? Pq é a solução que resolver os dois prinicipais pontos de preocupação de vcs. Não tem layout shift nem oculta informação. Se tiverem soluções inteligentes para mobile para evitar que os elementos firem multiplas linhas, o espaço vertical ocupado não vejo como critico. Não crítico ao ponto de valer a pena essas outras duas perdar.

matheusps commented 3 months ago

@lafray, acho que 5 e 6 tem o mesmo problema: As ações ficam quebradas em dois espaços, sendo eles:

  1. O checkbox no header da table, que tem a ação de selecionar todos
  2. A barra do header.

O gmail resolveu esse problema juntando o checkbox com essas ações:

Screenshot 2024-08-08 at 15 17 22
beatrizmilhomem commented 3 months ago

Oi pessoal! @malu-viana , conversamos agora durante o office hours, junto com @lafray , e pensamos em uma sugestão sobre como seguir agora: vcs decidem dentro do time qual o melhor caminho pro contexto atual (se o 5 ou o 6) e implementam o componente no time de vcs por enquanto, sem adicionar ainda à biblioteca.

Por que essa sugestão? Estamos num impasse em que nenhuma solução ainda parece a ideal, por isso está tão difícil chegar em um acordo. Entendemos que o problema maior pode estar, na verdade, no header do Collection. A ideia agora é discutir a revisão desse ponto, podemos começar por aqui https://github.com/vtex/shoreline/issues/1811.

Malu e Lais ficam ok de seguir assim?

malu-viana commented 3 months ago

Faz sentido para mim @beatrizmilhomem :)

lafray commented 3 months ago

As we had discussed, I created it in our only monorepo. It was created through this PR. I'm sharing it here because I thought you might be interested in taking a look (there's a lot of room for improvement since we had a significant time constraint). You can see how it's using the project's storybook (pnpm run docs). After you guys advance in defining the designer, who knows, maybe I'll help you create the version here for the shoreline.

beatrizmilhomem commented 3 months ago

Como essa discussão já foi concluída, vou fechar essa issue. Depois que o header do Collection for resolvido em https://github.com/vtex/shoreline/issues/1811 , uma nova issue pode ser criada com a nova proposta.