[Gastosabertos-dev] ao

Andres MRM andres em inventati.org
Sexta Março 6 21:29:47 UTC 2015


Quoting Luiz Armesto (2015-03-06 18:09:47)
> Eu troquei a implementação antiga do pubsub pelo PubSubJS[1], daí mudou o
> formato das mensagens. No lugar de dois pontos agora é um ponto, ficando "
> pubsub.publish('years.changed', {value: [2012]})"

Ah, deu certo! Que legal! =P
Consigo alterar o ano dos dados na tabela usando esse comando no console.

> A implementação da manipulação da url só trabalha com o fragmento do hash, o
> que vem depois do #. Então ele simula uma string de query colocando "?param=
> value" depois do #. Isso por que manipular o conteúdo do hash não faz com que a
> página seja recarregada, já manipular o a string real de query, o "?param=
> value" logo após o endereço, antes do #, faz com que o navegador faça uma nova
> requisição.
> 
> 
> Quando navega nas páginas ou altera a quantidade de itens não está alterando a
> parte da URL depois do #? Qual navegador está usando para eu testar aqui? Não
> está usando alguma versão antiga do js salva no cache?

Agora vi que muda a URL sim. Mas não altera a tabela...
Uso FF. Testei agora no Chromium e deu na mesma...
 
> 
> Vou instalar localmente com o mysql e dar uma pesquisada para ver o erro da
> conexão, mas acho que não tem tantos registros para dar pau numa contagem...
> sei lá.

Concordo...
> 
> 
> 
> [1] https://github.com/mroderick/PubSubJS
> 
> 2015-03-06 16:16 GMT-03:00 Andres MRM <andres em inventati.org>:
> 
> 
>     Tive o mesmo tipo de erro (a tabela não abriu).
>     Pelo que vi nos logs está dando: 'Lost connection to MySQL server during
>     query'
>     https://gist.github.com/andresmrm/3e2ac724d5c491607f09
>     Tem vários parecidos com esses lá.
>     Aparentemente o pau é na hora de 'X-Total-Count': revenue_data.count()
>     Será que é dado demais para ele contar? =P
> 
>     Outra coisa, Luiz, o pubsub é para estar funcionado?
>     Estou abrindo, por exemplo:
>     http://site.gastosabertos.org/receitas/?year=2014&level=2.3#2014/1?page=3&
>     year=2012&level=2.3
>     Indo no console e dando:
>     pubsub.publish('years:changed', {value: [2012]})
>     Mas ele está retornando 'false'
>     Apertar os botões da tabela, apesar de fazer duas requisições que retornam
>     200
>     OK, não está tendo efeito...
>     Aumentar o número de páginas da tabela também faz as requisições, mas não
>     altera nada na página...
> 
> 
>     Quoting Luiz Armesto (2015-03-04 13:43:11)
>     > Aconteceu aqui o problema de não carregar a tabela direito mas com uma
>     causa
>     > diferente das possibilidades levantadas. No caso o servidor da api deu
>     erro
>     > 500.
>     >
>     > Não consegui reproduzir o erro nem localmente nem no próprio servidor
>     (dando
>     > reload ou abrindo em outra aba o mesmo endereço da api, com os mesmos
>     > parâmetros. funcionou). 
>     > Precisaria ter acesso ao log do servidor para ver o que houve.
>     >
>     >
>     > []'s
>     >
>     > 2015-03-02 23:05 GMT-03:00 Luiz Armesto <luiz.armesto em gmail.com>:
>     >
>     >     2015-03-02 22:04 GMT-03:00 Edgar Zanella Alvarenga <e em vaz.io>:
>     >
>     >         Ok, vi com mais calma o código agora e seu email esclareceu
>     melhor
>     >         alguns pontos. Estava confuso com os eventos 'page.dt' e
>     'length.dt',
>     >         não sabia que eram eventos do próprio DataTables e pensei que os
>     >         tinha criado também.
>     >
>     >
>     >     É, isso não estava claro mesmo.
>     >      
>     >
>     >
>     >         Gostei de como fez, só acho que da linha 85 a 114 ficou um pouco
>     >         obfuscated, apesar de entender a razão de querer ter feito um
>     código
>     >         genéricopra lista de parâmetros em 'param'. Acho que seria melhor
>     >         ter um subscribe explícito por parâmetro e separar em funções
>     distintas
>     >         cada uma das cláusulas condicionais entre 103 e 107, entende, ao
>     >         invése de um setParam genérico.
>     >
>     >
>     >      Sobre as clausulas no setParam eu cheguei a fazer separado, mas
>     acabei
>     >     juntando justamente para aprovitar o código de "subscribe" genérico
>     (linhas
>     >     85-114).
>     >
>     >     Acho que separar os "subscribe" em dois explícitos para "page" e
>     >     "per_page_num" e um genérico (o atual) não teria problema, apesar de
>     >     introduzir código parcialmente repetido, mas se melhora a leitura e
>     >     compreensão vale a pena.
>     >     O que não dá é para remover completamente o código genérico que itera
>     nas
>     >     chaves dos parâmetros definidos na inicialização do objeto senão ele
>     deixa
>     >     de ser reaproveitável. Ficou um tanto obscuro mesmo, mas posso
>     melhorar com
>     >     um comentário explicando o que o trecho faz e o porquê.
>     >
>     >
>     >         Isso deixaria mais claro o código e mais separado a lógica a ser
>     >         realizada a cada mudança de parâmetro.
>     >
>     >         Tirando isso, maravilha, acho legal irmos por esse direção, me
>     parece
>     >         uma solução simples e elegante.
>     >
>     >         Quanto a dependência com o jquery, sim, devemos colocar isso via
>     >         require,
>     >         a idéia é que todo gerenciamento de dependência deja feito por
>     ele,
>     >         então considere esses imports via script como algo que vamos ter
>     >         que resolver.
>     >
>     >
>     >     blz
>     >      
>     >
>     >
>     >         Ah sim, o parâmetro code pro endpoint listrevenue já está
>     funcionando:
>     >
>     >         http://demo.gastosabertos.org/api/v1/receita/list?code=1.1.2&page
>     =0&
>     >         per_page_num=10&years=2014
>     >
>     >         Basta adicionar o code com parte do nível superior cujo subníveis
>     quer
>     >         consultar.
>     >
>     >
>     >     Boa, já inclui na tabela.
>     >      
>     >
>     >
>     >         E pra finalizar, sobre o Riot, eu só tinha visto o observer dele,
>     mas
>     >         nunca usei e não faço idéia se na prática ele iria nos ajudar ou
>     >         complicar
>     >         mais no nosso caso de uso, pelo menos no problema de
>     sincronização de
>     >         eventos. Eu só fiquei pensando se não era algo já resolvido por
>     um
>     >         desses frameworks da modinha ou libs simples como:
>     >
>     >         https://github.com/mroderick/PubSubJS
>     >         https://github.com/uxder/Radio
>     >
>     >         Que talvez evitem que tenhamos muito trabalho em resolver
>     problemas que
>     >         não são nossa prioridade no momento. Novamente, não conheço a
>     fundo
>     >         nenhuma dessa libs que citei e a única vantagem que vejo nelas é
>     >         estarem
>     >         desacopladas do JQuery, caso fossemos pra uma solução JQuery
>     free.
>     >
>     >
>     >     Vou ver essas libs, mas de qualquer modo estou usando o jQuery para
>     pub/sub
>     >     com facade, entre outras coisas, para usar uma interface com nomes de
>     >     métodos comuns a implementações de pub/sub, então se quisermos chutar
>     o
>     >     jQuery e usar uma lib dedicada será bem tranquilo. Ou adaptamos a
>     facade
>     >     para a nova lib ou, se a interface for a mesma que fiz, tiramos a
>     facade e
>     >     usamos direto a lib.
>     >      
>     >
>     >
>     >         Mas entendo o ponto de que estamos tentando sincronizar
>     componentes de
>     >         libs diferentes, com arquiteturas diferentes e no final se
>     fossemos pra
>     >         uma solução "mágica" acabaríamos tendo que fazer vários códigos
>     ao
>     >         redor
>     >         dessas bibliotecas pra conversarem entre si. E fiquei pensando na
>     parte
>     >         pra sincronizar as mudanças nas variáveis com alterações no URL,
>     >         leitura
>     >         do URL pros parâmetros nas diferentes visualizações e me
>     perguntei se
>     >         não tinha uma solução onde ganharíamos tudo isso pronto de
>     lambuja (a
>     >         man
>     >         can dream!).
>     >
>     >
>     >     Já enviei o código que estava fazendo em relação a URL usando hash e
>     o pub/
>     >     sub. Se tudo deu certo ao acessar http://site.gastosabertos.org/
>     receitas/#
>     >     2014/1.1.1?page=7 (e não estiver usando o js velho salvo no cache do
>     >     navegador) verá a lista exibindo a página 8 dos impostos de 2014. Se
>     >     navegar pelas páginas da tabela a URL deve ser atualizada e se usar
>     os
>     >     botões de back/forward do navegador a tabela deve se atualizar junto
>     com a
>     >     URL. Editar manualmente o ano (para periodo use hifen para separar o
>     ano de
>     >     inicio e de fim) e o código na URL também funciona.
>     >      
>     >
>     >
>     >         Enfim, acho uma boa irmos pela direção que tomou, só talvez
>     tornar isso
>     >         mais independente para que seja replicado nas outras páginas,
>     >         provavelmente
>     >         fazendo uma biblioteca, RSpubsub (Really Simple PubSub), mas esse
>     não
>     >         precisa
>     >         ser nossa prioridade agora.
>     >
>     >         Abs,
>     >         E.
>     >
>     >
>     >     []'s
>     >      
>     >
>     >
>     >         On 02/03/2015 19:27, Luiz Armesto wrote:
>     >
>     >             2015-03-02 17:30 GMT-03:00 Edgar Zanella Alvarenga <e em vaz.io
>     [39]>:
>     >
>     >
>     >                 Oi Luiz, ótimo! Dei uma olhada rápida no seu código e fiz
>     >                 alguns
>     >                 testes.
>     >                 Está legal, mas ocorreu mais de uma vez ao visitar o
>     >                 http://site.gastosabertos.org/receita [1]
>     >
>     >                 que o gráfico drilldown carregou, mas a tabela não. Uma
>     vez
>     >                 consegui identificar
>     >                 o erro, que foi não conseguir importar o Datatables,
>     talvez o
>     >                 servidor deles
>     >                 estava fora do ar.
>     >
>     >
>     >             Vou verificar isso. Além de problema no servidor deles pode
>     ter
>     >             sido
>     >             timeout do requirejs ou talvez tentou carregar o datatables
>     antes
>     >             do
>     >             jquery (atualmente o jquery está sendo carregado direto no
>     html,
>     >             com
>     >             tag script, mas o datatables via requirejs. Isso porque o
>     jquery já
>     >             estava sendo usado direto sem o requirejs e o datatables
>     identifica
>     >             se
>     >             tem alguma lib de AMD, no caso o requirejs, e se registra
>     direto
>     >             nela,
>     >             não deixando carregar colocando direto uma tag script com
>     ele,
>     >             então
>     >             tive que carregar usando o requirejs. Precisamos arrumar
>     isso, ou
>     >             usar
>     >             requirejs ou não usar, misturar é pedir problemas). 
>     >
>     >              
>     >
>     >
>     >                 Mas olhando seu código, fiquei encafifado com a
>     quantidade de
>     >                 código
>     >                 que escreveu pra registrar os eventos e não ficou claro
>     pra mim
>     >                 o
>     >                 quão
>     >                 fácil será fazer isso sincronizado com o gráfico de
>     barras. Se
>     >                 tivermos
>     >                 uma forma fácil de utilizar o modelo pusub que está
>     usando
>     >                 legal
>     >                 sem muito
>     >                 biolerplate code, ótimo. Mas fico em dúvida se
>     utilizarmos uma
>     >                 solução
>     >                 como o Riot js não seja melhor, pra não termos que
>     resolver
>     >                 novamente
>     >                 certos problemas. 
>     >
>     >
>     >              O que você acha? Por mim sem problemas
>     >
>     >
>     >                 s em uma mesma página. O quanto
>     >                 de código precisará ser replicado? Se conseguir fazer um
>     resumo
>     >                 bem breve
>     >                 do que tem em mente pra anotar os eventos e criar as
>     funções
>     >                 pra
>     >                 respondê-los
>     >                 seria legal.
>     >
>     >                 Pelo que olhei no riotjs não enxerguei uma solução mais
>     simples
>     >                 usando ele do que a que pensei. Nós temos que integrar
>     >                 componentes
>     >                 que são feitos com lib
>     >
>     >             s, então para sincronizar temos que escutar os eventos que
>     essas
>     >             libs
>     >             emitem quando o usuário interage com elas e chamar métodos
>     que elas
>     >             definem na API para alterar seus valores na hora de
>     sincronizar.
>     >             Não
>     >             vejo como as funcionalidades do riotjs de virtual DOM com
>     >             interpolação (o DOM que exibem os gráficos e as tabelas são
>     >             criadas pelas próprias libs externas, não temos controle
>     sobre
>     >             isso)
>     >             podem ajudar.
>     >
>     >             O que poderiamos usar do riotjs é a API de Observer deles,
>     mas o
>     >             jQuery já implementa isso (é o que estou usando) e já o temos
>     como
>     >             dependência.
>     >
>     >             Vocês chegaram a pensar em como sincronizar os vários
>     componentes
>     >             usando o riotjs e viram usos dele que eu não enxerguei?
>     >
>     >             Sobre a implementação do Sub/Pub, na verdade é apenas uma
>     facade
>     >             para a implementação de eventos do jQuery, são 7 linhas [0]
>     que
>     >             definem um objeto e redirecionam 3 métodos para o jQuery:
>     >
>     >              subscribe --> on
>     >              unsubscribe --> off
>     >              publish -- trigger
>     >
>     >             Para usar é simplesmente criar uma instância e se registrar
>     com o
>     >             "subscribe" para receber as notificações de uma determinada
>     >             mensagem
>     >             e mandar notificações com o "publish":
>     >
>     >             // Cria o objeto
>     >             var pubSub = new PubSub();
>     >
>     >             // Registra para receber notificações
>     >             pubSub.subscribe(nome_da_mensagem, function(evt, content) {
>     >               console.log(Mensagem recebida com o seguinte conteúdo: ,
>     >             content);
>     >             });
>     >
>     >             // Publica notificação
>     >             pubSub.publish(nome_da_mensagem, este é o conteúdo);
>     >
>     >
>     >             // Neste ponto foi exibido "Mensagem recebida com o seguinte
>     >             conteúdo: este é o conteúdo"
>     >
>     >             Então para usar o pub/sub é bem fácil e com muito pouco
>     código,
>     >             só precisa que todos os envolvidos na sincronização tenham
>     acesso
>     >             ao mesmo objeto de pub/sub e compartilhem de uma padronização
>     nos
>     >             nomes e formatos das mensagens enviadas, sem ter conhecimento
>     de
>     >             quem
>     >             são os demais participantes (desacoplados). Então se, por
>     exemplo,
>     >             a
>     >             tabela registrou para receber uma mensagem quando o código é
>     >             alterado, ela tera o mesmo comportamento independente se a
>     >             alteração
>     >             é proveniente de uma mudança na url, um clique no gráfico ou
>     uma
>     >             seleção num menu, só precisa que a mensagem seja publicada no
>     >             objeto pub/sub seguindo o padrão definido.
>     >
>     >             O que acontece, em relação a quantidade de código que
>     escrevi, para
>     >             ter mais linhas [1] do que 3 simples "pubSub.subscribe(...)"
>     (que
>     >             seria um para "page", um para "per_page_num" e um para
>     "years", que
>     >             são as três coisas que atualmente importam para a tabela) é
>     porque
>     >             eu fiz de um modo que o mesmo objeto pode ser reutilizado
>     para
>     >             tabelas
>     >             diferentes, que buscam os dados em outros endpoints que
>     tenham
>     >             parâmetros diferentes (ou mesmo para estender o funcionamento
>     da
>     >             tabela atual quando os outros parâmetros forem implementados,
>     como
>     >             o
>     >             "codes", sem precisar alterar o código).
>     >
>     >             Eu defino na criação do objeto quais são os parâmetros do
>     endpoint
>     >             que importam para a tabela, ou que poderão ser alterados
>     >             externamente
>     >             por outro componente, podendo definir um valor inicial [2],
>     então
>     >             eu
>     >             itero sobre os parâmetros registrando automaticamente [3].
>     >
>     >             Assim, se eu criar um objeto DataTable passando nas opções
>     "params:
>     >             { years: 2014, page: 0, per_page_num: 10  }" ele vai se
>     registrar
>     >             para as mensagens "years:changed", "page:changed" e
>     >             "per_page_num:changed" e quando qualquer um publicar uma
>     dessas
>     >             mensagens ele vai se atualizar. Quando tivermos implementado
>     o
>     >             parâmetro "codes" na endpoint "List revenues" basta alterar
>     na
>     >             criação do objetos incluindo esse parâmetro nas opções
>     (passando
>     >             a ser "params: { years: 2014, page: 0, per_page_num: 10 ,
>     codes:
>     >             null
>     >             }") que a tabela passará a responder também a mensagem
>     >             "codes:changed", armazenando internamente o valor (método
>     >             "setParam"
>     >             chamado pelo callback do "pubSub.subscribe"), que será
>     enviado na
>     >             requisição AJAX (no método "_ajaxRequest", que é usado pela
>     lib
>     >             DataTables, e é responsável por enviar todos os parâmetros
>     >             registrados).
>     >
>     >             Então para criar tabelas com dados diferentes, endpoint
>     diferente e
>     >             parâmetros diferentes, mas também facilmente sincronizável e
>     com
>     >             paginação via ajax, basta criar um objeto DataTable
>     informando qual
>     >             a url do endpoint, quais são os parametros e quais são os
>     campos do
>     >             json de cada coluna e pronto. Fazer o que está entre as
>     linhas 199
>     >             e
>     >             222 [4] com as devidas alterações, em especial em "columns" e
>     >             "params", sem precisar nem criar mais funções nem definir
>     outros
>     >             tipos de objetos. 
>     >
>     >             TL; DR;
>     >
>     >             Para sincronizar, o componente com o qual o usuário está
>     >             interagindo, por exemplo no caso do ano ser alterado, só terá
>     que
>     >             chamar "pubSub.publish(years:changed, {value: [anoMin,
>     anoMax]})" e
>     >             os
>     >             demais terem se registrado com "pubSub.subscribe
>     (years:changed,
>     >             callback)", e implementado a logica necessária no callback,
>     para
>     >             serem notificados e se manterem sincronizados.
>     >
>     >             O DataTable é mais complicado do que isso pois foi feito de
>     modo
>     >             genérico para ser reutilizado em outras páginas, pecisando
>     apenas
>     >             configurar algumas coisas na criação do objeto.
>     >
>     >
>     >             [0] https://github.com/okfn-brasil/gastos_abertos_website/
>     blob/
>     >             cd83cc446e6953b2281c7cebbdabc8f7d5e79772/frontend/src/
>     javascripts/
>     >             receitas/main.js#L188
>     >             [40]
>     >
>     >             [1] https://github.com/okfn-brasil/gastos_abertos_website/
>     blob/
>     >             cd83cc446e6953b2281c7cebbdabc8f7d5e79772/frontend/src/
>     javascripts/
>     >             receitas/main.js#L71
>     >             [41]
>     >
>     >             [2] https://github.com/okfn-brasil/gastos_abertos_website/
>     blob/
>     >             cd83cc446e6953b2281c7cebbdabc8f7d5e79772/frontend/src/
>     javascripts/
>     >             receitas/main.js#L211
>     >             [42]
>     >
>     >             [3] https://github.com/okfn-brasil/gastos_abertos_website/
>     blob/
>     >             cd83cc446e6953b2281c7cebbdabc8f7d5e79772/frontend/src/
>     javascripts/
>     >             receitas/main.js#L86
>     >             [43]
>     >
>     >             [4] https://github.com/okfn-brasil/gastos_abertos_website/
>     blob/
>     >             cd83cc446e6953b2281c7cebbdabc8f7d5e79772/frontend/src/
>     javascripts/
>     >             receitas/main.js#L199
>     >             [44]
>     >
>     >             []s
>     >
>     >              
>     >              Abs,
>     >              E.
>     >
>     >              On 02/03/2015 14:07, Luiz Armesto wrote:
>     >
>     >
>     >             Links:
>     >             ------
>     >             [1] http://site.gastosabertos.org/receita
>     >             [2] https://github.com/okfn-brasil/gastos_abertos/pull/134
>     >             [3] https://github.com/okfn-brasil/gastos_abertos/issues/121
>     >             [4] https://github.com/okfn-brasil/gastos_abertos/issues/132
>     >             [5] mailto:Gastosabertos-dev em lists.okfn.org
>     >             [6] https://lists.okfn.org/mailman/listinfo/gastosabertos-dev
>     >             [7] mailto:Gastosabertos-dev em lists.okfn.org
>     >             [8] https://lists.okfn.org/mailman/listinfo/gastosabertos-dev
>     >             [9] mailto:Gastosabertos-dev em lists.okfn.org
>     >             [10] https://lists.okfn.org/mailman/listinfo/
>     gastosabertos-dev
>     >             [11] mailto:Gastosabertos-dev em lists.okfn.org
>     >             [12] https://lists.okfn.org/mailman/listinfo/
>     gastosabertos-dev
>     >             [13] mailto:Gastosabertos-dev em lists.okfn.org
>     >             [14] https://lists.okfn.org/mailman/listinfo/
>     gastosabertos-dev
>     >             [15] mailto:Gastosabertos-dev em lists.okfn.org
>     >             [16] https://lists.okfn.org/mailman/listinfo/
>     gastosabertos-dev
>     >             [17]
>     >
>     >             http://demo.gastosabertos.org/receita/static/
>     total_by_year_by_code/
>     >             2014.json
>     >             [18] mailto:e em vaz.io
>     >             [19]
>     >
>     >             http://demo.gastosabertos.org/receita/static/
>     total_by_year_by_code/
>     >             2014.json
>     >             [20] http://demo.gastosabertos.org/api/v1/receita/
>     totaldrilldown?
>     >             year=2014
>     >             [21] http://demo.gastosabertos.org/api/v1/receita/
>     totaldrilldown?
>     >             year=2014
>     >             [22] mailto:Gastosabertos-dev em lists.okfn.org
>     >             [23] https://lists.okfn.org/mailman/listinfo/
>     gastosabertos-dev
>     >             [24] mailto:Gastosabertos-dev em lists.okfn.org
>     >             [25] https://lists.okfn.org/mailman/listinfo/
>     gastosabertos-dev
>     >             [26] mailto:Gastosabertos-dev em lists.okfn.org
>     >             [27] https://lists.okfn.org/mailman/listinfo/
>     gastosabertos-dev
>     >             [28] mailto:Gastosabertos-dev em lists.okfn.org
>     >             [29] https://lists.okfn.org/mailman/listinfo/
>     gastosabertos-dev
>     >             [30] https://github.com/okfn-brasil/gastos_abertos/pull/134
>     >             [31] https://github.com/okfn-brasil/gastos_abertos/issues/121
>     >             [32] mailto:Gastosabertos-dev em lists.okfn.org
>     >             [33] https://lists.okfn.org/mailman/listinfo/
>     gastosabertos-dev
>     >             [34] mailto:Gastosabertos-dev em lists.okfn.org
>     >             [35] https://lists.okfn.org/mailman/listinfo/
>     gastosabertos-dev
>     >             [36] mailto:e em vaz.io
>     >             [37] mailto:Gastosabertos-dev em lists.okfn.org
>     >             [38] https://lists.okfn.org/mailman/listinfo/
>     gastosabertos-dev
>     >             [39] mailto:e em vaz.io
>     >             [40]
>     >
>     >             https://github.com/okfn-brasil/gastos_abertos_website/blob/
>     >             cd83cc446e6953b2281c7cebbdabc8f7d5e79772/frontend/src/
>     javascripts/
>     >             receitas/main.js#L188
>     >             [41]
>     >
>     >             https://github.com/okfn-brasil/gastos_abertos_website/blob/
>     >             cd83cc446e6953b2281c7cebbdabc8f7d5e79772/frontend/src/
>     javascripts/
>     >             receitas/main.js#L71
>     >             [42]
>     >
>     >             https://github.com/okfn-brasil/gastos_abertos_website/blob/
>     >             cd83cc446e6953b2281c7cebbdabc8f7d5e79772/frontend/src/
>     javascripts/
>     >             receitas/main.js#L211
>     >             [43]
>     >
>     >             https://github.com/okfn-brasil/gastos_abertos_website/blob/
>     >             cd83cc446e6953b2281c7cebbdabc8f7d5e79772/frontend/src/
>     javascripts/
>     >             receitas/main.js#L86
>     >             [44]
>     >
>     >             https://github.com/okfn-brasil/gastos_abertos_website/blob/
>     >             cd83cc446e6953b2281c7cebbdabc8f7d5e79772/frontend/src/
>     javascripts/
>     >             receitas/main.js#L199
>     >
>     >
>     >         _______________________________________________
>     >         Gastosabertos-dev mailing list
>     >         Gastosabertos-dev em lists.okfn.org
>     >         https://lists.okfn.org/mailman/listinfo/gastosabertos-dev
>     >
>     >
>     >
>     >
>     >     --
>     >     Luiz Armesto
>     >
>     >
>     >
>     >
>     > --
>     > Luiz Armesto
>     _______________________________________________
>     Gastosabertos-dev mailing list
>     Gastosabertos-dev em lists.okfn.org
>     https://lists.okfn.org/mailman/listinfo/gastosabertos-dev
> 
> 
> 
> 
> --
> Luiz Armesto



Mais detalhes sobre a lista de discussão Gastosabertos-dev