Commit aa0e62e2b99408d5f2f9fd4cd77b604b5d96b5c2

Authored by Leonardo Merlin
2 parents 082f347c c07e7c4b

Merge branch 'merlin' into rafael

Conflicts:
	src/assets/images/icons/sprite.png
Showing 112 changed files with 2453 additions and 2055 deletions   Show diff stats

Too many changes.

To preserve performance only 100 of 112 files displayed.

1 # Dialoga App 1 # Dialoga App
2 2
3 -Start development: 3 +Convenções:
  4 +
  5 +- Os *programas* são **topics**;
  6 +- Os *temas* são **categories**;
  7 +- Um *grupo de programas* é um **discussion** (um grupo de topics);
  8 +- As *propostas* são **proposals**;
  9 +
  10 +
  11 +Para iniciar o desenvolvimento:
4 12
5 ```bash 13 ```bash
6 # dev with no proxy (local data) 14 # dev with no proxy (local data)
7 -gulp serve  
8 -json-server data.js -p 9000 -w data.js 15 +gulp serve && json-server data.js -p 9000 -w data.js
9 16
10 # dev with proxy to hom server 17 # dev with proxy to hom server
11 gulp serve --target="http://hom.login.dialoga.gov.br" 18 gulp serve --target="http://hom.login.dialoga.gov.br"
@@ -14,7 +21,7 @@ gulp serve --target="http://hom.login.dialoga.gov.br" @@ -14,7 +21,7 @@ gulp serve --target="http://hom.login.dialoga.gov.br"
14 gulp serve --target="http://login.dialoga.gov.br" 21 gulp serve --target="http://login.dialoga.gov.br"
15 ``` 22 ```
16 23
17 -# Project Decisions 24 +##### Referências
18 25
19 - [generator-gulp-angular](https://github.com/Swiip/generator-gulp-angular) 26 - [generator-gulp-angular](https://github.com/Swiip/generator-gulp-angular)
20 - Angular 27 - Angular
TROUBLESHOOTING.md 0 → 100644
@@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
  1 +- Erro com `lwip` ou `make: g++: Command not found`
  2 + - Solução:
  3 + 1. Instalar dependências do g++: `sudo apt-get install build-essential g++`
  4 + 2. Reinstalar o sprity:
  5 + 1. desinstalar: ``npm uninstall sprity``
  6 + 2. limpar cache: ``npm cache clear``
  7 + 3. instalar: ``npm install sprity``
0 \ No newline at end of file 8 \ No newline at end of file
@@ -29,26 +29,22 @@ module.exports = function () { @@ -29,26 +29,22 @@ module.exports = function () {
29 "id": 180, 29 "id": 180,
30 "slug": "saude", 30 "slug": "saude",
31 "image": null 31 "image": null
32 - },  
33 - { 32 + }, {
34 "name": "Segurança Pública", 33 "name": "Segurança Pública",
35 "id": 182, 34 "id": 182,
36 "slug": "seguranca-publica", 35 "slug": "seguranca-publica",
37 "image": null 36 "image": null
38 - },  
39 - { 37 + }, {
40 "name": "Educação", 38 "name": "Educação",
41 "id": 181, 39 "id": 181,
42 "slug": "educacao", 40 "slug": "educacao",
43 "image": null 41 "image": null
44 - },  
45 - { 42 + }, {
46 "name": "Redução da Pobreza", 43 "name": "Redução da Pobreza",
47 "id": 183, 44 "id": 183,
48 "slug": "reducao-da-pobreza", 45 "slug": "reducao-da-pobreza",
49 "image": null 46 "image": null
50 - },  
51 - { 47 + }, {
52 "name": "Cultura", 48 "name": "Cultura",
53 "id": 194, 49 "id": 194,
54 "slug": "cultura", 50 "slug": "cultura",
@@ -91,8 +87,7 @@ module.exports = function () { @@ -91,8 +87,7 @@ module.exports = function () {
91 "allow_members_to_edit": false 87 "allow_members_to_edit": false
92 }, 88 },
93 "position": 14 89 "position": 14
94 - },  
95 - { 90 + }, {
96 "id": 103521, 91 "id": 103521,
97 "abstract": "<p>Mais atendimento nos municípios, mais saúde para quem mais precisa.</p>", 92 "abstract": "<p>Mais atendimento nos municípios, mais saúde para quem mais precisa.</p>",
98 "title": "Mais Médicos", 93 "title": "Mais Médicos",
@@ -115,8 +110,7 @@ module.exports = function () { @@ -115,8 +110,7 @@ module.exports = function () {
115 "allow_members_to_edit": false 110 "allow_members_to_edit": false
116 }, 111 },
117 "position": 1 112 "position": 1
118 - },  
119 - { 113 + }, {
120 "id": 103457, 114 "id": 103457,
121 "abstract": "<p>Ação conjunta e cooperação transfronteiriça.</p>", 115 "abstract": "<p>Ação conjunta e cooperação transfronteiriça.</p>",
122 "title": "Proteção das Fronteiras", 116 "title": "Proteção das Fronteiras",
@@ -139,8 +133,7 @@ module.exports = function () { @@ -139,8 +133,7 @@ module.exports = function () {
139 "allow_members_to_edit": false 133 "allow_members_to_edit": false
140 }, 134 },
141 "position": 15 135 "position": 15
142 - },  
143 - { 136 + }, {
144 "id": 103612, 137 "id": 103612,
145 "abstract": "<p>Garantir água para beber e produzir.</p>", 138 "abstract": "<p>Garantir água para beber e produzir.</p>",
146 "title": "Cisternas", 139 "title": "Cisternas",
@@ -163,8 +156,7 @@ module.exports = function () { @@ -163,8 +156,7 @@ module.exports = function () {
163 "allow_members_to_edit": false 156 "allow_members_to_edit": false
164 }, 157 },
165 "position": 20 158 "position": 20
166 - },  
167 - { 159 + }, {
168 "id": 103442, 160 "id": 103442,
169 "abstract": "<p>Complemento à renda e acompanhamento em educação e saúde.</p>", 161 "abstract": "<p>Complemento à renda e acompanhamento em educação e saúde.</p>",
170 "title": "Bolsa Família", 162 "title": "Bolsa Família",
@@ -187,8 +179,7 @@ module.exports = function () { @@ -187,8 +179,7 @@ module.exports = function () {
187 "allow_members_to_edit": false 179 "allow_members_to_edit": false
188 }, 180 },
189 "position": 17 181 "position": 17
190 - },  
191 - { 182 + }, {
192 "id": 103673, 183 "id": 103673,
193 "abstract": "<p>A melhor escolha é se informar.</p>", 184 "abstract": "<p>A melhor escolha é se informar.</p>",
194 "title": "Incentivo ao Parto Normal", 185 "title": "Incentivo ao Parto Normal",
@@ -211,8 +202,7 @@ module.exports = function () { @@ -211,8 +202,7 @@ module.exports = function () {
211 "allow_members_to_edit": false 202 "allow_members_to_edit": false
212 }, 203 },
213 "position": 6 204 "position": 6
214 - },  
215 - { 205 + }, {
216 "id": 103397, 206 "id": 103397,
217 "abstract": "<p>Renda, inclusão produtiva e acesso a serviços.</p>", 207 "abstract": "<p>Renda, inclusão produtiva e acesso a serviços.</p>",
218 "title": "Brasil Sem Miséria", 208 "title": "Brasil Sem Miséria",
@@ -235,8 +225,7 @@ module.exports = function () { @@ -235,8 +225,7 @@ module.exports = function () {
235 "allow_members_to_edit": false 225 "allow_members_to_edit": false
236 }, 226 },
237 "position": 18 227 "position": 18
238 - },  
239 - { 228 + }, {
240 "id": 121505, 229 "id": 121505,
241 "abstract": "<p>Um novo jeito de ver e de fazer cultura</p>", 230 "abstract": "<p>Um novo jeito de ver e de fazer cultura</p>",
242 "title": "Agenda Seculo XXI", 231 "title": "Agenda Seculo XXI",
@@ -259,8 +248,7 @@ module.exports = function () { @@ -259,8 +248,7 @@ module.exports = function () {
259 "author_name": "leonardo.merlin" 248 "author_name": "leonardo.merlin"
260 }, 249 },
261 "position": null 250 "position": null
262 - },  
263 - { 251 + }, {
264 "id": 121526, 252 "id": 121526,
265 "abstract": "<p>Cultura e arte como base para a educação integral</p>", 253 "abstract": "<p>Cultura e arte como base para a educação integral</p>",
266 "title": "Cultura e Educação", 254 "title": "Cultura e Educação",
@@ -283,8 +271,7 @@ module.exports = function () { @@ -283,8 +271,7 @@ module.exports = function () {
283 "author_name": "leonardo.merlin" 271 "author_name": "leonardo.merlin"
284 }, 272 },
285 "position": null 273 "position": null
286 - },  
287 - { 274 + }, {
288 "id": 103485, 275 "id": 103485,
289 "abstract": "<p>Caminho para uma educação de qualidade.</p>", 276 "abstract": "<p>Caminho para uma educação de qualidade.</p>",
290 "title": "Valorização dos Professores", 277 "title": "Valorização dos Professores",
@@ -307,8 +294,7 @@ module.exports = function () { @@ -307,8 +294,7 @@ module.exports = function () {
307 "allow_members_to_edit": false 294 "allow_members_to_edit": false
308 }, 295 },
309 "position": 11 296 "position": 11
310 - },  
311 - { 297 + }, {
312 "id": 103663, 298 "id": 103663,
313 "abstract": "<p>Mais educação profissional e tecnológica, mais desenvolvimento</p>", 299 "abstract": "<p>Mais educação profissional e tecnológica, mais desenvolvimento</p>",
314 "title": "Ensino Técnico", 300 "title": "Ensino Técnico",
@@ -331,8 +317,7 @@ module.exports = function () { @@ -331,8 +317,7 @@ module.exports = function () {
331 "allow_members_to_edit": false 317 "allow_members_to_edit": false
332 }, 318 },
333 "position": 10 319 "position": 10
334 - },  
335 - { 320 + }, {
336 "id": 121514, 321 "id": 121514,
337 "abstract": "<p>Reconhecimento, fortalecimento e mobilização das comunidades que fazem cultura no Brasil</p>", 322 "abstract": "<p>Reconhecimento, fortalecimento e mobilização das comunidades que fazem cultura no Brasil</p>",
338 "title": "Cultura Viva", 323 "title": "Cultura Viva",
@@ -355,8 +340,7 @@ module.exports = function () { @@ -355,8 +340,7 @@ module.exports = function () {
355 "author_name": "leonardo.merlin" 340 "author_name": "leonardo.merlin"
356 }, 341 },
357 "position": null 342 "position": null
358 - },  
359 - { 343 + }, {
360 "id": 103592, 344 "id": 103592,
361 "abstract": "<p>Garantir acesso à proteção social.</p>", 345 "abstract": "<p>Garantir acesso à proteção social.</p>",
362 "title": "Assistência Social", 346 "title": "Assistência Social",
@@ -379,8 +363,7 @@ module.exports = function () { @@ -379,8 +363,7 @@ module.exports = function () {
379 "allow_members_to_edit": false 363 "allow_members_to_edit": false
380 }, 364 },
381 "position": 19 365 "position": 19
382 - },  
383 - { 366 + }, {
384 "id": 103426, 367 "id": 103426,
385 "abstract": "<p>Da saúde se cuida todos os dias.</p>", 368 "abstract": "<p>Da saúde se cuida todos os dias.</p>",
386 "title": "Vida saudável", 369 "title": "Vida saudável",
@@ -403,8 +386,7 @@ module.exports = function () { @@ -403,8 +386,7 @@ module.exports = function () {
403 "allow_members_to_edit": false 386 "allow_members_to_edit": false
404 }, 387 },
405 "position": 7 388 "position": 7
406 - },  
407 - { 389 + }, {
408 "id": 103507, 390 "id": 103507,
409 "abstract": "<p>Tecnologia a serviço da segurança do cidadão.</p>", 391 "abstract": "<p>Tecnologia a serviço da segurança do cidadão.</p>",
410 "title": "Sinesp", 392 "title": "Sinesp",
@@ -427,8 +409,7 @@ module.exports = function () { @@ -427,8 +409,7 @@ module.exports = function () {
427 "allow_members_to_edit": false 409 "allow_members_to_edit": false
428 }, 410 },
429 "position": 12 411 "position": 12
430 - },  
431 - { 412 + }, {
432 "id": 103359, 413 "id": 103359,
433 "abstract": "<p>Acesso a exames e consultas com especialistas.</p>", 414 "abstract": "<p>Acesso a exames e consultas com especialistas.</p>",
434 "title": "Mais Especialidades", 415 "title": "Mais Especialidades",
@@ -451,8 +432,7 @@ module.exports = function () { @@ -451,8 +432,7 @@ module.exports = function () {
451 "allow_members_to_edit": false 432 "allow_members_to_edit": false
452 }, 433 },
453 "position": 2 434 "position": 2
454 - },  
455 - { 435 + }, {
456 "id": 103683, 436 "id": 103683,
457 "abstract": "<p>Saúde não tem preço.</p>", 437 "abstract": "<p>Saúde não tem preço.</p>",
458 "title": "Aqui tem Farmácia Popular", 438 "title": "Aqui tem Farmácia Popular",
@@ -475,8 +455,7 @@ module.exports = function () { @@ -475,8 +455,7 @@ module.exports = function () {
475 "allow_members_to_edit": false 455 "allow_members_to_edit": false
476 }, 456 },
477 "position": 5 457 "position": 5
478 - },  
479 - { 458 + }, {
480 "id": 103695, 459 "id": 103695,
481 "abstract": "<p>Novo modelo de atuação em Segurança Pública.</p>", 460 "abstract": "<p>Novo modelo de atuação em Segurança Pública.</p>",
482 "title": "Segurança Pública Integrada", 461 "title": "Segurança Pública Integrada",
@@ -499,8 +478,7 @@ module.exports = function () { @@ -499,8 +478,7 @@ module.exports = function () {
499 "allow_members_to_edit": false 478 "allow_members_to_edit": false
500 }, 479 },
501 "position": 13 480 "position": 13
502 - },  
503 - { 481 + }, {
504 "id": 103379, 482 "id": 103379,
505 "abstract": "<p>Resgate e atendimento 24 horas, sete dias da semana.</p>", 483 "abstract": "<p>Resgate e atendimento 24 horas, sete dias da semana.</p>",
506 "title": "SAMU 192 e UPAs", 484 "title": "SAMU 192 e UPAs",
@@ -523,8 +501,7 @@ module.exports = function () { @@ -523,8 +501,7 @@ module.exports = function () {
523 "allow_members_to_edit": false 501 "allow_members_to_edit": false
524 }, 502 },
525 "position": 4 503 "position": 4
526 - },  
527 - { 504 + }, {
528 "id": 103494, 505 "id": 103494,
529 "abstract": "<p>Da Educação Infantil ao Ensino Médio.</p>", 506 "abstract": "<p>Da Educação Infantil ao Ensino Médio.</p>",
530 "title": "Educação Básica", 507 "title": "Educação Básica",
@@ -547,8 +524,7 @@ module.exports = function () { @@ -547,8 +524,7 @@ module.exports = function () {
547 "allow_members_to_edit": false 524 "allow_members_to_edit": false
548 }, 525 },
549 "position": 8 526 "position": 8
550 - },  
551 - { 527 + }, {
552 "id": 103644, 528 "id": 103644,
553 "abstract": "<p>Um caminho de oportunidades com o Enem: Sisu, Prouni, Fies, Ciência sem Fronteiras</p>", 529 "abstract": "<p>Um caminho de oportunidades com o Enem: Sisu, Prouni, Fies, Ciência sem Fronteiras</p>",
554 "title": "Ensino Superior", 530 "title": "Ensino Superior",
@@ -571,8 +547,7 @@ module.exports = function () { @@ -571,8 +547,7 @@ module.exports = function () {
571 "allow_members_to_edit": false 547 "allow_members_to_edit": false
572 }, 548 },
573 "position": 9 549 "position": 9
574 - },  
575 - { 550 + }, {
576 "id": 121499, 551 "id": 121499,
577 "abstract": "<p>Valorização da arte e da cultura em suas múltiplas possibilidades</p>", 552 "abstract": "<p>Valorização da arte e da cultura em suas múltiplas possibilidades</p>",
578 "title": "Política Nacional das Artes", 553 "title": "Política Nacional das Artes",
@@ -595,8 +570,7 @@ module.exports = function () { @@ -595,8 +570,7 @@ module.exports = function () {
595 "author_name": "leonardo.merlin" 570 "author_name": "leonardo.merlin"
596 }, 571 },
597 "position": null 572 "position": null
598 - },  
599 - { 573 + }, {
600 "id": 103472, 574 "id": 103472,
601 "abstract": "<p>Polícia Federal, Polícia Rodoviária Federal e Força Nacional de Segurança Pública.</p>", 575 "abstract": "<p>Polícia Federal, Polícia Rodoviária Federal e Força Nacional de Segurança Pública.</p>",
602 "title": "Forças Federais de Segurança", 576 "title": "Forças Federais de Segurança",
@@ -619,8 +593,7 @@ module.exports = function () { @@ -619,8 +593,7 @@ module.exports = function () {
619 "allow_members_to_edit": false 593 "allow_members_to_edit": false
620 }, 594 },
621 "position": 16 595 "position": 16
622 - },  
623 - { 596 + }, {
624 "id": 121492, 597 "id": 121492,
625 "abstract": "<p>Apoio ao audiovisual brasileiro: ampliação da produção, da difusão e do acesso</p>", 598 "abstract": "<p>Apoio ao audiovisual brasileiro: ampliação da produção, da difusão e do acesso</p>",
626 "title": "Brasil de Todas as Telas", 599 "title": "Brasil de Todas as Telas",
@@ -643,8 +616,7 @@ module.exports = function () { @@ -643,8 +616,7 @@ module.exports = function () {
643 "author_name": "leonardo.merlin" 616 "author_name": "leonardo.merlin"
644 }, 617 },
645 "position": null 618 "position": null
646 - },  
647 - { 619 + }, {
648 "id": 121521, 620 "id": 121521,
649 "abstract": "<p>Mais acesso a cultura para trabalhadores e trabalhadoras</p>", 621 "abstract": "<p>Mais acesso a cultura para trabalhadores e trabalhadoras</p>",
650 "title": "Vale-Cultura", 622 "title": "Vale-Cultura",
@@ -667,8 +639,7 @@ module.exports = function () { @@ -667,8 +639,7 @@ module.exports = function () {
667 "author_name": "leonardo.merlin" 639 "author_name": "leonardo.merlin"
668 }, 640 },
669 "position": null 641 "position": null
670 - },  
671 - { 642 + }, {
672 "id": 103416, 643 "id": 103416,
673 "abstract": "<p>Estrutura adequada para atender melhor a população na atenção básica.</p>", 644 "abstract": "<p>Estrutura adequada para atender melhor a população na atenção básica.</p>",
674 "title": "Melhorar os Postos de Saúde", 645 "title": "Melhorar os Postos de Saúde",
@@ -691,8 +662,7 @@ module.exports = function () { @@ -691,8 +662,7 @@ module.exports = function () {
691 "allow_members_to_edit": false 662 "allow_members_to_edit": false
692 }, 663 },
693 "position": 3 664 "position": 3
694 - },  
695 - { 665 + }, {
696 "id": 121501, 666 "id": 121501,
697 "abstract": "<p>Preservação do patrimônio e qualidade de vida para os cidadãos</p>", 667 "abstract": "<p>Preservação do patrimônio e qualidade de vida para os cidadãos</p>",
698 "title": "PAC Cidades Históricas", 668 "title": "PAC Cidades Históricas",
@@ -734,5 +704,149 @@ module.exports = function () { @@ -734,5 +704,149 @@ module.exports = function () {
734 "article":{"id":121521,"body":"\u003Cdiv class=\"col-xs-12\"\u003E\r\n\u003Cdiv class=\"row\"\u003E\r\n\u003Cdiv class=\"col-md-12\"\u003E\r\n\u003Ch2\u003EVale-Cultura\u003Csmall\u003EMais acesso \u00e0 cultura para trabalhadores e trabalhadoras\u003C/small\u003E\u003C/h2\u003E\r\n\u003C/div\u003E\r\n\u003C/div\u003E\r\n\u003Cdiv class=\"row\"\u003E\r\n\u003Cdiv class=\"col-md-12\"\u003E\r\n\u003Ch3\u003ELivros, shows e espet\u00e1culos para todos.\u003C/h3\u003E\r\n\u003C/div\u003E\r\n\u003C/div\u003E\r\n\u003Cdiv class=\"row\"\u003E\r\n\u003Cdiv class=\"col-md-6 col-sm-6 vcenter\"\u003E\u003Cimg class=\"img-responsive\" src=\"http://gestao.dialoga.gov.br/dialoga/dialoga-brasil/vale-cultura/imagens/vale-cultura1.jpg\" alt=\"\" /\u003E\u003C/div\u003E\r\n\u003Cdiv class=\"col-md-6 col-sm-6 vcenter\"\u003E\r\n\u003Cp\u003EO Vale-Cultura incentiva as empresas a oferecer aos seus funcion\u00e1rios acesso a livros, revistas, ingressos para cinemas, teatros, shows, instrumentos musicais e cursos de arte e cultura.\u003C/p\u003E\r\n\u003Cp\u003EO benef\u00edcio \u00e9 garantido por meio de um cart\u00e3o magn\u00e9tico pr\u00e9-pago, v\u00e1lido em todo os pa\u00eds. Mensalmente, esse cart\u00e3o recebe cr\u00e9dito de R$ 50, que pode ser acumulado para despesas maiores.\u003C/p\u003E\r\n\u003Cp\u003EA ades\u00e3o das empresas \u00e9 facultativa e os custos s\u00e3o livres de encargos sociais e trabalhistas. Aquelas que t\u00eam lucro real podem deduzir at\u00e9 1% do Imposto de Renda devido.\u003C/p\u003E\r\n\u003C/div\u003E\r\n\u003C/div\u003E\r\n\u003Cbr /\u003E\r\n\u003Cdiv class=\"row\"\u003E\r\n\u003Cdiv class=\"col-md-6 col-sm-6 vcenter\"\u003E\r\n\u003Cblockquote\u003E\r\n\u003Cp class=\"text-center\"\u003EEm pouco mais de um ano, o Vale-Cultura j\u00e1 mobiliza mais de R$140 milh\u00f5es e beneficia cerca de 420 mil trabalhadores e trabalhadoras.\u003C/p\u003E\r\n\u003C/blockquote\u003E\r\n\u003C/div\u003E\r\n\u003Cdiv class=\"col-md-6 col-sm-6 vcenter\"\u003E\r\n\u003Cdiv class=\"embed-responsive embed-responsive-16by9\"\u003E\u003Ciframe src=\"https://www.youtube.com/embed/KKmZh5T46g8?rel=0\" frameborder=\"0\" width=\"560\" height=\"315\"\u003E\u003C/iframe\u003E\u003C/div\u003E\r\n\u003C/div\u003E\r\n\u003C/div\u003E\r\n\u003Cdiv class=\"row\"\u003E\r\n\u003Cdiv class=\"col-md-12\"\u003E\r\n\u003Ch3\u003ECompromissos\u003C/h3\u003E\r\n\u003C/div\u003E\r\n\u003C/div\u003E\r\n\u003Cdiv class=\"row\"\u003E\r\n\u003Cdiv class=\"col-md-6 col-sm-6 vcenter\"\u003E\u003Cimg class=\"img-responsive\" src=\"http://gestao.dialoga.gov.br/dialoga/dialoga-brasil/vale-cultura/imagens/vale-cultura3.jpg\" alt=\"\" /\u003E\u003C/div\u003E\r\n\u003Cdiv class=\"col-md-6 col-sm-6 vcenter\"\u003E\r\n\u003Cul class=\"list-unstyled\"\u003E\r\n\u003Cli class=\"bullet\"\u003E\u003Cstrong\u003EAmpliar a ades\u00e3o de empresas e trabalhadores\u003C/strong\u003E\u003C/li\u003E\r\n\u003Cli class=\"bullet\"\u003E\u003Cstrong\u003EAmpliar a rede de estabelecimentos que recebem o Vale-Cultura.\u003C/strong\u003E\u003C/li\u003E\r\n\u003C/ul\u003E\r\n\u003C/div\u003E\r\n\u003C/div\u003E\r\n\u003C/div\u003E"} 704 "article":{"id":121521,"body":"\u003Cdiv class=\"col-xs-12\"\u003E\r\n\u003Cdiv class=\"row\"\u003E\r\n\u003Cdiv class=\"col-md-12\"\u003E\r\n\u003Ch2\u003EVale-Cultura\u003Csmall\u003EMais acesso \u00e0 cultura para trabalhadores e trabalhadoras\u003C/small\u003E\u003C/h2\u003E\r\n\u003C/div\u003E\r\n\u003C/div\u003E\r\n\u003Cdiv class=\"row\"\u003E\r\n\u003Cdiv class=\"col-md-12\"\u003E\r\n\u003Ch3\u003ELivros, shows e espet\u00e1culos para todos.\u003C/h3\u003E\r\n\u003C/div\u003E\r\n\u003C/div\u003E\r\n\u003Cdiv class=\"row\"\u003E\r\n\u003Cdiv class=\"col-md-6 col-sm-6 vcenter\"\u003E\u003Cimg class=\"img-responsive\" src=\"http://gestao.dialoga.gov.br/dialoga/dialoga-brasil/vale-cultura/imagens/vale-cultura1.jpg\" alt=\"\" /\u003E\u003C/div\u003E\r\n\u003Cdiv class=\"col-md-6 col-sm-6 vcenter\"\u003E\r\n\u003Cp\u003EO Vale-Cultura incentiva as empresas a oferecer aos seus funcion\u00e1rios acesso a livros, revistas, ingressos para cinemas, teatros, shows, instrumentos musicais e cursos de arte e cultura.\u003C/p\u003E\r\n\u003Cp\u003EO benef\u00edcio \u00e9 garantido por meio de um cart\u00e3o magn\u00e9tico pr\u00e9-pago, v\u00e1lido em todo os pa\u00eds. Mensalmente, esse cart\u00e3o recebe cr\u00e9dito de R$ 50, que pode ser acumulado para despesas maiores.\u003C/p\u003E\r\n\u003Cp\u003EA ades\u00e3o das empresas \u00e9 facultativa e os custos s\u00e3o livres de encargos sociais e trabalhistas. Aquelas que t\u00eam lucro real podem deduzir at\u00e9 1% do Imposto de Renda devido.\u003C/p\u003E\r\n\u003C/div\u003E\r\n\u003C/div\u003E\r\n\u003Cbr /\u003E\r\n\u003Cdiv class=\"row\"\u003E\r\n\u003Cdiv class=\"col-md-6 col-sm-6 vcenter\"\u003E\r\n\u003Cblockquote\u003E\r\n\u003Cp class=\"text-center\"\u003EEm pouco mais de um ano, o Vale-Cultura j\u00e1 mobiliza mais de R$140 milh\u00f5es e beneficia cerca de 420 mil trabalhadores e trabalhadoras.\u003C/p\u003E\r\n\u003C/blockquote\u003E\r\n\u003C/div\u003E\r\n\u003Cdiv class=\"col-md-6 col-sm-6 vcenter\"\u003E\r\n\u003Cdiv class=\"embed-responsive embed-responsive-16by9\"\u003E\u003Ciframe src=\"https://www.youtube.com/embed/KKmZh5T46g8?rel=0\" frameborder=\"0\" width=\"560\" height=\"315\"\u003E\u003C/iframe\u003E\u003C/div\u003E\r\n\u003C/div\u003E\r\n\u003C/div\u003E\r\n\u003Cdiv class=\"row\"\u003E\r\n\u003Cdiv class=\"col-md-12\"\u003E\r\n\u003Ch3\u003ECompromissos\u003C/h3\u003E\r\n\u003C/div\u003E\r\n\u003C/div\u003E\r\n\u003Cdiv class=\"row\"\u003E\r\n\u003Cdiv class=\"col-md-6 col-sm-6 vcenter\"\u003E\u003Cimg class=\"img-responsive\" src=\"http://gestao.dialoga.gov.br/dialoga/dialoga-brasil/vale-cultura/imagens/vale-cultura3.jpg\" alt=\"\" /\u003E\u003C/div\u003E\r\n\u003Cdiv class=\"col-md-6 col-sm-6 vcenter\"\u003E\r\n\u003Cul class=\"list-unstyled\"\u003E\r\n\u003Cli class=\"bullet\"\u003E\u003Cstrong\u003EAmpliar a ades\u00e3o de empresas e trabalhadores\u003C/strong\u003E\u003C/li\u003E\r\n\u003Cli class=\"bullet\"\u003E\u003Cstrong\u003EAmpliar a rede de estabelecimentos que recebem o Vale-Cultura.\u003C/strong\u003E\u003C/li\u003E\r\n\u003C/ul\u003E\r\n\u003C/div\u003E\r\n\u003C/div\u003E\r\n\u003C/div\u003E"}
735 }); 705 });
736 706
  707 +
  708 + // Random topics / Programas aleatorios - 1 por tema
  709 + // path: /api/v1/dialoga_plugin/random_topics/103358
  710 + // Like: http://hom.dialoga.gov.br/api/v1/dialoga_plugin/random_topics/103358
  711 + // ?fields[]=id&fields[]=title&fields[]=slug&fields[]=abstract&fields[]=body&fields[]=categories&fields[]=setting&fields[]=ranking_position&fields[]=position&fields[]=children_count&fields[]=hits&fields[]=votes_for&fields[]=votes_against&fields[]=tag_list
  712 + data.dialoga_plugin = {
  713 + "articles": [
  714 + {
  715 + "ranking_position": null,
  716 + "id": 116089,
  717 + "body": "<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-md-12\">\r\n<h2>Cultura e Educação<small>Cultura e arte como base para a educação integral.</small></h2>\r\n</div>\r\n</div>\r\n<div class=\"row\">\r\n<div class=\"col-md-12\"><img class=\"img-responsive center-block\" src=\"http://hom.gestao.dialoga.gov.br/dialoga/dialoga-brasil/cultura-e-educacao/imagens/cultura-educacao-imagem1.jpg\" alt=\"\" /></div>\r\n</div>\r\n<br />\r\n<div class=\"row\">\r\n<div class=\"col-md-12\">\r\n<p>A aproximação entre cultura e educação é estratégica para o desenvolvimento cultural do país e para a qualificação da educação brasileira.</p>\r\n<p> </p>\r\n<h3>Mais Cultura nas Escolas promove ensino com criatividade</h3>\r\n</div>\r\n</div>\r\n<div class=\"row\">\r\n<div class=\"col-md-6 col-sm-6\">\r\n<p>É mais fácil aprender quando as abordagens pedagógicas são criativas e têm relação com a realidade cultural das crianças e jovens. Com o Mais Cultura nas Escolas, o ensino de crianças, adolescentes e jovens vincula-se às experiências culturais e artísticas das comunidades em que vivem.</p>\r\n<blockquote>\r\n<p class=\"text-center\">São priorizadas as escolas que têm maior número de estudantes beneficiários do Bolsa Família</p>\r\n</blockquote>\r\n<img class=\"img-responsive center-block\" style=\"width: 100%;\" src=\"http://hom.gestao.dialoga.gov.br/dialoga/dialoga-brasil/cultura-e-educacao/imagens/cultura-educacao-imagem3.jpg\" alt=\"Imagem de Vídeo\" /></div>\r\n<div class=\"col-md-6 col-sm-6\"><img class=\"img-responsive center-block\" src=\"http://hom.gestao.dialoga.gov.br/dialoga/dialoga-brasil/cultura-e-educacao/imagens/cultura-educacao-imagem2.jpg\" alt=\"Conexão Felipe Camarão\" /> <br /> <img class=\"img-responsive center-block\" src=\"http://hom.gestao.dialoga.gov.br/dialoga/dialoga-brasil/cultura-e-educacao/imagens/cultura-educacao-imagem4.jpg\" alt=\"Programa mais cultura nas escolas\" /></div>\r\n</div>\r\n</div>\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-md-12\">\r\n<h3>União dos saberes científicos e populares</h3>\r\n</div>\r\n</div>\r\n<div class=\"row\">\r\n<div class=\"col-md-4 col-sm-4\"><img class=\"img-responsive center-block\" src=\"http://hom.gestao.dialoga.gov.br/dialoga/dialoga-brasil/cultura-e-educacao/imagens/cultura-educacao-imagem5.jpg\" alt=\"\" /></div>\r\n<div class=\"col-md-8 col-sm-8\">\r\n<p>O Programa Mais Cultura nas Universidades utiliza os <em>campi</em> e os institutos federais de ensino como centros irradiadores de produção artística e cultural para as comunidades. São realizadas ações de extensão, pesquisa e inovação em conjunto com grupos artísticos locais.</p>\r\n<p>Um total de 28 universidades e institutos federais foram apoiados diretamente pelo programa e outras 73 instituições federais já apresentaram planos de cultura.</p>\r\n</div>\r\n</div>\r\n</div>\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-md-12\">\r\n<h3>Pronatec Cultura fomenta a economia e amplia a renda</h3>\r\n</div>\r\n</div>\r\n<div class=\"row\">\r\n<div class=\"col-md-6 col-sm-6\">\r\n<p>O Pronatec Cultura oferece qualificação profissional que fortalece as cadeias produtivas da cultura, promovendo a formalização do setor, inclusão profissional e aumento da renda.</p>\r\n<p>Está presente em 228 municípios de 19 estados brasileiros, com 7.702 pessoas formadas até o primeiro semestre de 2015.</p>\r\n<blockquote>\r\n<p class=\"text-center\">São 65 cursos de formação como fotógrafo, vitrinista, iluminador cênico, sonoplasta, ilustrador e assistente de produção, ofertados pelos Institutos Federais, Sistema S e escolas profissionalizantes</p>\r\n</blockquote>\r\n</div>\r\n<div class=\"col-md-6 col-sm-6\"><img class=\"img-responsive center-block\" src=\"http://hom.gestao.dialoga.gov.br/dialoga/dialoga-brasil/cultura-e-educacao/imagens/cultura-educacao-imagem6.jpg\" alt=\"\" /></div>\r\n</div>\r\n</div>",
  718 + "abstract": "<p>Cultura e arte como base para a educação integral</p>",
  719 + "title": "Cultura e Educação",
  720 + "categories": [
  721 + {
  722 + "name": "Cultura",
  723 + "id": 194,
  724 + "slug": "cultura"
  725 + }
  726 + ],
  727 + "votes_for": 0,
  728 + "votes_against": 0,
  729 + "setting": {
  730 + "color": "",
  731 + "allow_members_to_edit": false,
  732 + "moderate_comments": false,
  733 + "comment_paragraph_plugin_activate": false,
  734 + "author_name": "Admin DEDES"
  735 + },
  736 + "position": null,
  737 + "hits": 17,
  738 + "tag_list": [],
  739 + "children_count": 2,
  740 + "slug": "cultura-e-educacao"
  741 + }, {
  742 + "ranking_position": null,
  743 + "id": 103644,
  744 + "body": "<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-md-12\">\r\n<h2>Ensino Superior<small>Um caminho de oportunidades com o Enem: Sisu, Prouni, Fies, Ciência sem Fronteiras</small></h2>\r\n</div>\r\n</div>\r\n<div class=\"row\">\r\n<div class=\"col-md-12\">\r\n<h3>Enem - Exame Nacional do Ensino Médio</h3>\r\n</div>\r\n</div>\r\n<div class=\"row\">\r\n<div class=\"col-md-6 col-sm-6\">\r\n<p>O Exame Nacional do Ensino Médio (Enem) abre portas para que todos os brasileiros trilhem, em igualdade de condições e de acordo com seus méritos como estudantes, um <strong>caminho de oportunidades</strong> por meio dos ensinos técnico e superior.</p>\r\n<br />\r\n<h4>Cada vez mais estudantes realizam o Enem</h4>\r\n<p>Na edição de 2014, o Enem teve quase <strong>9 milhões de inscritos e se consolidou como o maior exame deste tipo no Brasil e o segundo maior no mundo.</strong></p>\r\n<blockquote>\r\n<p class=\"text-center\">Com o Enem, várias possibilidades se abrem para o estudante, de acordo com o seu desempenho nos exames.</p>\r\n</blockquote>\r\n</div>\r\n<div class=\"col-md-6 col-sm-6\"><img class=\"img-responsive center-block\" src=\"http://dialoga.gov.br/dialoga/dialoga-brasil/ensino-superior/imagens/foto-1.jpg\" alt=\"\" width=\"375\" height=\"417\" /></div>\r\n</div>\r\n</div>\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-md-12\"><img class=\"img-responsive center-block\" src=\"http://dialoga.gov.br/dialoga/dialoga-brasil/ensino-superior/imagens/infografico-1.jpg\" alt=\"\" width=\"305\" height=\"269\" /></div>\r\n</div>\r\n</div>\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-md-12\">\r\n<h3>SISU - Sistema de Seleção Unificada</h3>\r\n</div>\r\n</div>\r\n<div class=\"row\">\r\n<div class=\"col-md-12\">\r\n<p>Em outros tempos, o jovem que quisesse ingressar no ensino superior fazia inscrição no vestibular para um único curso de uma única universidade. Apenas estudantes com melhores condições financeiras podiam se inscrever em mais instituições e em diferentes locais do país.</p>\r\n<p>Hoje, com o SISU, a realidade é outra. O jovem, independentemente de sua condição social, usando a nota de um único exame – o Enem, feito em um único local e em uma mesma data, tem direito de disputar <strong>milhares de vagas, em vários cursos</strong> das melhores Instituições públicas e privadas de ensino superior, de todo o país.</p>\r\n<p>Durante o período de inscrição, o aluno pode acompanhar diariamente, pela internet, como está a procura pelos cursos do seu interesse, para alinhar suas escolhas e seus planos de estudo com a nota que obteve no Enem.</p>\r\n</div>\r\n</div>\r\n<div class=\"row\">\r\n<div class=\"col-md-12\"><img class=\"img-responsive center-block\" src=\"http://dialoga.gov.br/dialoga/dialoga-brasil/ensino-superior/imagens/infografico-2.jpg\" alt=\"\" width=\"546\" height=\"293\" /></div>\r\n</div>\r\n</div>\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-md-12\">\r\n<h3>PROUNI: Universidade para Todos</h3>\r\n</div>\r\n</div>\r\n<div class=\"row\">\r\n<div class=\"col-md-6 col-sm-6\"><img class=\"img-responsive center-block\" src=\"http://dialoga.gov.br/dialoga/dialoga-brasil/ensino-superior/imagens/enem-imagem4.jpg\" alt=\"\" /></div>\r\n<div class=\"col-md-6 col-sm-6\">\r\n<p>O Programa Universidade para Todos (Prouni) foi criado em 2004 para ampliar e democratizar o acesso de estudantes de baixa renda ao ensino superior no Brasil.</p>\r\n<p>O Prouni concede bolsas integrais e parciais de 50% em instituições privadas de ensino superior para estudantes que ainda não têm um diploma de nível superior. O programa já totaliza mais de 1,69 milhão de bolsas concedidas, desde a sua criação, em 2004.</p>\r\n<p>Para concorrer a uma das bolsas, o aluno tem que ter no mínimo 450 pontos no Enem, não ter tirado zero na redação, ter cursado todo o ensino médio em escola pública ou como bolsista integral em escola particular. A renda bruta da família também é considerada no acesso às bolsas: deve ser menor que 1 ½ salário mínimo por pessoa para bolsa integral e menor que 3 salários mínimos por pessoa para bolsa de 50%.</p>\r\n</div>\r\n</div>\r\n</div>\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-md-12\">\r\n<h3>FIES: Fundo de Financiamento Estudantil para acesso ao ensino superior</h3>\r\n</div>\r\n</div>\r\n<div class=\"row\">\r\n<div class=\"col-md-6 col-sm-6\"><img class=\"img-responsive center-block\" src=\"http://dialoga.gov.br/dialoga/dialoga-brasil/ensino-superior/imagens//infografico-3.jpg\" alt=\"\" width=\"281\" height=\"234\" /></div>\r\n<div class=\"col-md-6 col-sm-6\">\r\n<p>Com quase 2 milhões de contratos firmados e 1.770 instituições participantes, o Fies se tornou um importante instrumento para quem pretende ingressar em uma instituição privada de ensino superior.</p>\r\n<p>As adequações pelas quais o Fies está passando garantem a sua sustentabilidade, asseguram a qualidade dos cursos financiados e beneficiam diretamente o estudante que realmente precisa do financiamento. Nenhum estudante que participa do Fies deixará de receber o benefício e o governo vai zelar pelo bom funcionamento do programa.</p>\r\n</div>\r\n</div>\r\n</div>\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-md-12\">\r\n<h3>SISUTEC: mais opções para crescer</h3>\r\n</div>\r\n</div>\r\n<div class=\"row\">\r\n<div class=\"col-md-12\">\r\n<p>Criado em 2013, o Sistema de Seleção Unificada da Educação Profissional e Tecnológica é mais uma opção para o estudante que faz o Enem. O Sisutec faz parte do Programa Nacional de Acesso ao Ensino Técnico e Emprego (Pronatec) e oferece vagas gratuitas em cursos técnicos.</p>\r\n</div>\r\n</div>\r\n</div>\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-md-12\">\r\n<h3>Ciência sem Fronteiras:<br />conhecimento avançado no exterior</h3>\r\n</div>\r\n</div>\r\n<div class=\"row\">\r\n<div class=\"col-md-6 col-sm-6\">\r\n<p>O Ciência sem Fronteiras proporciona aos estudantes brasileiros de graduação e de pós-graduação oportunidades de intercâmbio internacional, para estudar e pesquisar nas melhores universidades do mundo.</p>\r\n<p>Podem participar alunos de instituições públicas ou particulares de todo o país em áreas essenciais para o  desenvolvimento científico e tecnológico.</p>\r\n<p>Na primeira fase do programa, mais de 100 mil estudantes se beneficiaram dessa importante oportunidade. Em breve novos editais serão publicados, com a abertura de novas vagas.</p>\r\n</div>\r\n<div class=\"col-md-6 col-sm-6\"><img class=\"img-responsive center-block\" src=\"http://dialoga.gov.br/dialoga/dialoga-brasil/ensino-superior/imagens/infografico-4.jpg\" alt=\"\" width=\"226\" height=\"191\" /></div>\r\n</div>\r\n</div>\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-md-12\">\r\n<h3>Lei das Cotas</h3>\r\n</div>\r\n</div>\r\n<div class=\"row\">\r\n<div class=\"col-md-12\">\r\n<p>Todas as universidades públicas federais e os institutos federais de tecnologia reservam uma parte das suas vagas para alunos que estudaram em escolas públicas. Desde 2012, as cotas estão sendo implantadas gradualmente, até atingir, em 2016, a metade das vagas existentes.</p>\r\n<p>Das vagas reservadas para egressos de escolas públicas, metade é destinada a estudantes de famílias com renda mensal de até um salario mínimo e meio.</p>\r\n<p>O preenchimento destas vagas também leva em conta critérios de cor ou raça de acordo com as estatísticas do IBGE para cada estado.</p>\r\n<p>Após dois anos da implantação de Lei das Cotas (Lei nº 12.711, de 29 de agosto de 2012), em 2014, todos os institutos federais atenderam ao percentual mínimo de 25%, previsto para aquele ano; 85% atingiram a meta de 2015; 78% já atingiram a meta prevista para 2016 - 50% das vagas.</p>\r\n<p>No caso das Universidades Federais, todas atenderam, em 2014, ao percentual mínimo previsto de 25%; 64% atingiram antecipadamente a meta de 2015; 56% atingiram, com antecedência, a meta prevista para 2016.</p>\r\n<p>Em 2014, nos institutos federais, 23% das vagas foram reservadas para pretos, pardos e indígenas e, nas Universidades Federais, foram 20%.</p>\r\n</div>\r\n<div class=\"col-md-12\"><img class=\"img-responsive center-block\" src=\"http://dialoga.gov.br/dialoga/dialoga-brasil/ensino-superior/imagens/infografico-5.jpg\" alt=\"\" width=\"749\" height=\"223\" /></div>\r\n</div>\r\n</div>",
  745 + "abstract": "<p>Um caminho de oportunidades com o Enem: Sisu, Prouni, Fies, Ciência sem Fronteiras</p>",
  746 + "title": "Ensino Superior",
  747 + "categories": [
  748 + {
  749 + "name": "Educação",
  750 + "id": 181,
  751 + "slug": "educacao"
  752 + }
  753 + ],
  754 + "votes_for": 0,
  755 + "votes_against": 0,
  756 + "setting": {
  757 + "color": "#cfe2f3",
  758 + "moderate_comments": false,
  759 + "comment_paragraph_plugin_activate": false,
  760 + "author_name": "Ronald Emerson Scherolt da Costa",
  761 + "allow_members_to_edit": false
  762 + },
  763 + "position": 9,
  764 + "hits": 54,
  765 + "tag_list": [],
  766 + "children_count": 7,
  767 + "slug": "ensino-superior"
  768 + }, {
  769 + "ranking_position": null,
  770 + "id": 103442,
  771 + "body": "<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-md-12\">\r\n<h2>Bolsa Família <small>Complemento à renda e acompanhamento em educação e saúde.</small></h2>\r\n</div>\r\n</div>\r\n<div class=\"row\">\r\n<div class=\"col-md-12\"><img class=\"img-responsive center-block\" src=\"http://dialoga.gov.br/dialoga/dialoga-brasil/bolsa-familia/imagens/educacao-bolsa-familia-imagem1.png\" alt=\"\" width=\"748\" height=\"280\" /></div>\r\n<div class=\"col-md-12\"><br />\r\n<p>O Bolsa Família é um programa que complementa mensalmente a renda de 14 milhões de famílias pobres, garante que crianças e adolescentes permaneçam na escola e acompanha a saúde de crianças, de mulheres grávidas e daquelas que estão amamentando.</p>\r\n</div>\r\n</div>\r\n</div>\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-md-6 col-sm-6\">\r\n<h3>Educação no Bolsa Família</h3>\r\n<p>Na educação, o Bolsa Família faz o acompanhamento mensal da frequência escolar de 17 milhões de crianças e adolescentes de famílias de baixa renda. Também ajuda a identificar dificuldades de acesso e de permanência dos estudantes na escola.</p>\r\n</div>\r\n<div class=\"col-md-6 col-sm-6\"><img class=\"img-responsive center-block\" src=\"http://dialoga.gov.br/dialoga/dialoga-brasil/bolsa-familia/imagens/educacao-bolsa-familia-imagem2.jpg\" alt=\"\" /></div>\r\n</div>\r\n</div>\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-md-12\"><img class=\"img-responsive center-block\" src=\"http://dialoga.gov.br/dialoga/dialoga-brasil/bolsa-familia/imagens/educacao-bolsa-familia-imagem3.png\" alt=\"\" /></div>\r\n</div>\r\n</div>\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-md-6 col-sm-6\"><img class=\"img-responsive center-block\" src=\"http://dialoga.gov.br/dialoga/dialoga-brasil/bolsa-familia/imagens/educacao-bolsa-familia-imagem4.png\" alt=\"\" /></div>\r\n<div class=\"col-md-6 col-sm-6\">\r\n<h3>Saúde no Bolsa Família</h3>\r\n<p>Na saúde, o Programa monitora a vacinação, o peso e a altura das crianças com menos de 7 anos. Também faz o acompanhamento do pré-natal das gestantes e orienta as mulheres em fase de amamentação.</p>\r\n<p>Mais de 9 milhões de famílias são atendidas na área da saúde pelo Bolsa Família e os efeitos do acompanhamento são percebidos na vida das pessoas, na comprovada redução da mortalidade infantil e no crescimento saudável das crianças.</p>\r\n</div>\r\n</div>\r\n</div>\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-md-6 col-sm-6\">\r\n<h3>Redução de quase 1 cm do déficit de altura das crianças de 5 anos do Bolsa Família</h3>\r\n<img class=\"img-responsive center-block\" src=\"http://dialoga.gov.br/dialoga/dialoga-brasil/bolsa-familia/imagens/educacao-bolsa-familia-imagem5.jpg\" alt=\"\" /></div>\r\n<div class=\"col-md-6 col-sm-6\"> </div>\r\n</div>\r\n</div>\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-md-12 col-sm-12\">\r\n<h3>As crianças estão mais saudáveis e altas</h3>\r\n<p>Com a redução da desnutrição crônica, o déficit de estatura entre as crianças do Bolsa Família diminui 51%, o equivalente a quase 1 centímetro. A queda foi verificada em pesquisa que acompanhou 360 mil crianças beneficiadas ao longo de cinco anos seguidos, em que foram medidas e pesadas.</p>\r\n<p> </p>\r\n<h3>Cadastro Único para acessar políticas públicas</h3>\r\n</div>\r\n<div class=\"col-md-12 col-sm-12\">\r\n<p>Para participar do Programa, a família faz um cadastro com informações sobre moradia, renda, escolaridade e condições de vida. Este é o Cadastro Único para Programas Sociais do Governo Federal, um mapa social que permite aos governos planejarem suas ações, a partir da identificação das necessidades básicas das famílias.</p>\r\n<p>A orientação e o encaminhamento das famílias são feitos pela rede de assistência social para que os beneficiários do Bolsa Família acessem também outros programas como o <strong>Pronatec, o </strong><strong>Luz para Todos e o</strong><strong> Minha Casa</strong>, <strong>Minha Vida</strong>.</p>\r\n</div>\r\n</div>\r\n</div>\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-md-12 col-sm-12\">\r\n<h3>Quem recebe o Bolsa Família</h3>\r\n</div>\r\n<div class=\"col-md-12 col-sm-12\">\r\n<p>Podem participar as famílias registradas no Cadastro Único, desde que:</p>\r\n<ul class=\"list-styled\">\r\n<li>Com renda mensal, por pessoa, de até R$ 77, mesmo que não tenham gestantes, crianças ou adolescentes;</li>\r\n<li>Com renda mensal, por pessoa, de até R$ 154, que tenham gestantes, crianças ou adolescentes na família.</li>\r\n</ul>\r\n<p>O valor repassado depende do <strong>tamanho da família</strong>, da <strong>idade dos seus membros</strong> e da sua <strong>renda</strong>. Há benefícios específicos para famílias com crianças, jovens até 17 anos, gestantes e mães que amamentam.</p>\r\n</div>\r\n</div>\r\n</div>\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-md-12 col-sm-12\">\r\n<h3>Você sabia?</h3>\r\n</div>\r\n<div class=\"col-md-12 col-sm-12\">\r\n<ul class=\"list-styled \">\r\n<li><strong>O valor médio pago aos beneficiários do Bolsa Família é de R$ 168,00 mensais.</strong></li>\r\n<li><strong>As famílias que participam do Programa têm, em média, 2 filhos.</strong></li>\r\n</ul>\r\n</div>\r\n<div class=\"col-md-12 col-sm-12\">\r\n<blockquote class=\"text-center\">\r\n<p>Em 11 anos, 3,1 milhões de famílias saíram voluntariamente do programa Bolsa Família.</p>\r\n</blockquote>\r\n</div>\r\n</div>\r\n</div>\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-md-6 col-sm-6\"><img class=\"img-responsive center-clock\" src=\"http://dialoga.gov.br/dialoga/dialoga-brasil/bolsa-familia/imagens/educacao-bolsa-familia-imagem7.jpg\" alt=\"\" /></div>\r\n<div class=\"col-md-6 col-sm-6\">\r\n<h3>Trabalho no Bolsa Família</h3>\r\n<p>Os beneficiários do Bolsa Família trabalham e trabalham muito.</p>\r\n<p>A participação dos adultos beneficiários no mercado de trabalho formal e informal é igual à dos demais brasileiros.</p>\r\n</div>\r\n</div>\r\n</div>\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-md-12 col-sm-12\"><img class=\"img-responsive center-block\" src=\"http://dialoga.gov.br/dialoga/dialoga-brasil/bolsa-familia/imagens/educacao-bolsa-familia-imagem8.jpg\" alt=\"\" /></div>\r\n</div>\r\n</div>\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-md-12\">\r\n<h3>Controle e transparência</h3>\r\n<p>O governo está atento para que o benefício só chegue a quem realmente precisa. Há um trabalho contínuo e rigoroso para garantir o controle e a transparência do Programa Bolsa Família e o registro de irregularidades é muito baixo.</p>\r\n<ul class=\"list-styled \">\r\n<li>A lista dos beneficiários com o valor do benefício que recebem é mantida pública, no Portal da Transparência;</li>\r\n<li>Todos os beneficiários têm que atualizar o seu cadastro a cada dois anos;</li>\r\n<li>O governo realiza cruzamentos do Cadastro Único com outras bases de dados, rotineiramente.</li>\r\n</ul>\r\n</div>\r\n</div>\r\n</div>\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-md-12\">\r\n<h3>Acompanhe</h3>\r\n<p>Todo cidadão tem o direito de saber como o governo utiliza os recursos públicos. Para o Bolsa Família, existe um canal direto e gratuito para que qualquer pessoa possa obter informações ou fazer sugestões, reclamações e denúncias: <strong>0800 707 2003</strong>.</p>\r\n</div>\r\n</div>\r\n</div>\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-md-12\">\r\n<h3>A renda do Bolsa Família fortalece a economia local e o desenvolvimento do País</h3>\r\n</div>\r\n<div class=\"col-md-6 col-sm-6\">\r\n<p><strong>Com o Bolsa Família</strong> todos ganham. O programa beneficia diretamente mais de 50 milhões de pessoas pobres, mas seus resultados vão além do combate à pobreza.</p>\r\n<p>O dinheiro repassado para as famílias beneficiadas fica no município, circula na economia local e gera mais trabalho e renda para outras pessoas, contribuindo para o desenvolvimento do País.</p>\r\n</div>\r\n<div class=\"col-md-6 col-sm-6\"><img class=\"img-responsive center-block\" src=\"http://dialoga.gov.br/dialoga/dialoga-brasil/bolsa-familia/imagens/educacao-bolsa-familia-imagem10.jpg\" alt=\"\" /></div>\r\n</div>\r\n<div class=\"row\">\r\n<div class=\"col-md-12\">\r\n<p>O Bolsa Família faz tanto pelo Brasil que todos os brasileiros acabam sendo beneficiados por ele, direta ou indiretamente, com a movimentação da economia e com a inclusão social..</p>\r\n</div>\r\n</div>\r\n</div>",
  772 + "abstract": "<p>Complemento à renda e acompanhamento em educação e saúde.</p>",
  773 + "title": "Bolsa Família",
  774 + "categories": [
  775 + {
  776 + "name": "Redução da Pobreza",
  777 + "id": 183,
  778 + "slug": "reducao-da-pobreza"
  779 + }
  780 + ],
  781 + "votes_for": 0,
  782 + "votes_against": 0,
  783 + "setting": {
  784 + "color": "#ff9900",
  785 + "moderate_comments": false,
  786 + "comment_paragraph_plugin_activate": false,
  787 + "author_name": "Ronald Emerson Scherolt da Costa",
  788 + "allow_members_to_edit": false
  789 + },
  790 + "position": 17,
  791 + "hits": 68,
  792 + "tag_list": [],
  793 + "children_count": 9,
  794 + "slug": "bolsa-familia"
  795 + }, {
  796 + "ranking_position": null,
  797 + "id": 103379,
  798 + "body": "<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-md-12\">\r\n<h2>SAMU 192 e UPAs <small>Resgate e atendimento 24 horas, sete dias por semana.</small></h2>\r\n</div>\r\n</div>\r\n<div class=\"row\">\r\n<div class=\"col-md-12\">\r\n<p class=\"text-center\"><img class=\"img-responsive center-block\" src=\"http://dialoga.gov.br/dialoga/dialoga-brasil/urgencia-e-emergencia/imagens/img-destaque-1.jpg\" alt=\"Ambulancha e SAMU 192\" /></p>\r\n<p>O SAMU 192 foi criado em 2003 e chega a 75% da população brasileira, garantindo socorro e transporte de emergência. São 3.300 ambulâncias (vans, motos, lanchas e helicópteros).</p>\r\n</div>\r\n</div>\r\n</div>\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-md-12\">\r\n<h3>SAMU 192 já chega a 153,9 milhões de pessoas</h3>\r\n<p class=\"text-center\"><img class=\"img-responsive center-block\" src=\"http://dialoga.gov.br/dialoga/dialoga-brasil/samu-192-e-upas/imagens/grafico-1.jpg\" alt=\"Em 2005 o SAMU chegou à 60 milhões de pessoas. Em 2015 o SAMU chegou à 153,9 milhões de pessoas.\" width=\"725\" height=\"138\" /></p>\r\n</div>\r\n</div>\r\n</div>\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-md-12\">\r\n<h3>UPA - Unidades de Pronto Atendimento</h3>\r\n</div>\r\n</div>\r\n<div class=\"row\">\r\n<div class=\"col-md-6\"><img class=\"img-responsive center-block\" src=\"http://dialoga.gov.br/dialoga/dialoga-brasil/urgencia-e-emergencia/imagens/img-destaque-2.jpg\" alt=\"UPA 24h\" width=\"374\" height=\"346\" /></div>\r\n<div class=\"col-md-6\">\r\n<p>As Unidades de Pronto Atendimento podem resolver 90% das urgências e emergências de atendimento à saúde, como fraturas, problemas de pressão, derrames e infartos.</p>\r\n<p>As UPAs fazem parte de uma rede de atendimento, complementando as emergências dos hospitais e a internação domiciliar. Assim, as UPAs ajudam a diminuir a demanda sobre os pronto-socorros dos hospitais, que devem receber e atender rapidamente os casos mais graves e que exigem imediata internação.</p>\r\n<blockquote>\r\n<p class=\"text-center\">Há 400 UPAs em funcionamento no Brasil.</p>\r\n</blockquote>\r\n<p>Os serviços de atendimento para urgências e emergências estão sendo integrados e ampliados.</p>\r\n</div>\r\n</div>\r\n</div>\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-md-12\">\r\n<h3>Compromissos</h3>\r\n</div>\r\n</div>\r\n<div class=\"row\">\r\n<div class=\"col-md-6\"><img class=\"img-responsive center-block\" src=\"http://dialoga.gov.br/dialoga/dialoga-brasil/samu-192-e-upas/imagens/grafico-2.jpg\" alt=\"Imagem da rede de atenção as urgências e emergências. Posto de saúde, SAMU, UPA 24h, UBS e Hospital\" width=\"536\" height=\"402\" /></div>\r\n<div class=\"col-md-6\">\r\n<ul class=\"list-unstyled\">\r\n<li>Levar o atendimento do SAMU 192 para toda a população brasileira.</li>\r\n<li>Garantir a expansão das Unidades de Pronto Atendimento (UPAs) em todas as regiões do país.</li>\r\n<li>Garantir à população o atendimento em hospitais de referência para situações de urgência (cirurgias, internações e UTIs).</li>\r\n</ul>\r\n</div>\r\n</div>\r\n</div>",
  799 + "abstract": "<p>Resgate e atendimento 24 horas, sete dias da semana.</p>",
  800 + "title": "SAMU 192 e UPAs",
  801 + "categories": [
  802 + {
  803 + "name": "Saúde",
  804 + "id": 180,
  805 + "slug": "saude"
  806 + }
  807 + ],
  808 + "votes_for": 0,
  809 + "votes_against": 0,
  810 + "setting": {
  811 + "color": "#45818e",
  812 + "moderate_comments": false,
  813 + "comment_paragraph_plugin_activate": false,
  814 + "author_name": "Ronald Emerson Scherolt da Costa",
  815 + "allow_members_to_edit": false
  816 + },
  817 + "position": 4,
  818 + "hits": 72,
  819 + "tag_list": [],
  820 + "children_count": 13,
  821 + "slug": "samu-192-e-upas"
  822 + }, {
  823 + "ranking_position": null,
  824 + "id": 103390,
  825 + "body": "<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-md-12\">\r\n<h2>Crack, é possível vencer!<small>Prevenção, tratamento e enfrentamento ao tráfico.</small></h2>\r\n</div>\r\n</div>\r\n<div class=\"row\">\r\n<div class=\"col-md-12\"><img class=\"img-responsive center-block\" src=\"http://dialoga.gov.br/dialoga/dialoga-brasil/crack-e-possivel-vencer/imagens/crack-img-1.jpg\" alt=\"\" /></div>\r\n</div>\r\n</div>\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-md-12\">\r\n<p>O problema das drogas é um desafio ao mesmo tempo urgente e complexo. Requer medidas preventivas, de combate ao tráfico e, principalmente, oferta de serviços de saúde e assistência social.</p>\r\n<p>O programa “Crack, é possível vencer” envolve ações em três eixos: cuidado, autoridade e prevenção.</p>\r\n<p>O “<strong>cuidado</strong>” abrange a ampliação e a melhoria do atendimento para pessoas com problemas causados pelas drogas e para suas famílias, nas áreas de saúde e assistência social.</p>\r\n<p>No eixo “<strong>autoridade</strong>”, o foco é a integração de inteligência e cooperação entre forças policiais federais e estaduais. Envolve policiamento ostensivo nos pontos de uso e venda de drogas e a revitalização desses espaços, melhorando-os para toda a comunidade.</p>\r\n<p>Na área de “<strong>prevenção</strong>” são realizadas ações especiais em escolas e nas comunidades, assim como iniciativas de comunicação e informação para a população em geral.</p>\r\n<p><strong>Muitos resultados</strong> positivos <strong>foram</strong> alcançados <strong>de 2011 a 2014</strong>.</p>\r\n</div>\r\n</div>\r\n</div>\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-md-12 list-container-border\">\r\n<h4>CUIDADO - Saúde e assistência</h4>\r\n<ul class=\"list-unstyled no-border\">\r\n<li>2.200 Centros de Atenção Psicossocial (CAPS)</li>\r\n<li>360 CAPS Álcool e Drogas</li>\r\n<li>60 Unidades de Acolhimento</li>\r\n<li>8.034 vagas em comunidades terapêuticas</li>\r\n</ul>\r\n</div>\r\n</div>\r\n<div class=\"row\">\r\n<div class=\"col-md-12 list-container-border\">\r\n<h4>AUTORIDADE - Combate ao tráfico</h4>\r\n<ul class=\"list-unstyled no-border\">\r\n<li>Intensificação das operações</li>\r\n<li>7.700 profissionais de segurança pública capacitados</li>\r\n<li>Instalação de 26 grupos de investigações sensíveis da Polícia Federal</li>\r\n</ul>\r\n</div>\r\n</div>\r\n<div class=\"row\">\r\n<div class=\"col-md-12 list-container-border\">\r\n<h4>PREVENÇÃO</h4>\r\n<ul class=\"list-unstyled no-border\">\r\n<li>367 mil funcionários capacitados na temática de drogas em todo o País</li>\r\n<li>4 mil ligações-dia e 230 mil atendimentos efetivos no ligue 132, serviço gratuito de atendimento telefônico para informações sobre drogas</li>\r\n</ul>\r\n</div>\r\n</div>\r\n</div>",
  826 + "abstract": "<p>Prevenção, tratamento e enfrentamento ao tráfico.</p>",
  827 + "title": "Crack, é possível vencer!",
  828 + "categories": [
  829 + {
  830 + "name": "Segurança Pública",
  831 + "id": 182,
  832 + "slug": "seguranca-publica"
  833 + }
  834 + ],
  835 + "votes_for": 0,
  836 + "votes_against": 0,
  837 + "setting": {
  838 + "color": "#00ff00",
  839 + "moderate_comments": false,
  840 + "comment_paragraph_plugin_activate": false,
  841 + "author_name": "Ronald Emerson Scherolt da Costa",
  842 + "allow_members_to_edit": false
  843 + },
  844 + "position": 14,
  845 + "hits": 44,
  846 + "tag_list": [],
  847 + "children_count": 7,
  848 + "slug": "crack-e-possivel-vencer"
  849 + }
  850 + ]};
737 return data; 851 return data;
738 }; 852 };
src/app/components/article-box/article-box.directive.js
@@ -9,14 +9,11 @@ @@ -9,14 +9,11 @@
9 function articleBox($rootScope) { 9 function articleBox($rootScope) {
10 10
11 /** @ngInject */ 11 /** @ngInject */
12 - function ArticleBoxController(ArticleService, $scope, $state, Slug, $log) { 12 + function ArticleBoxController($state, $log) {
13 $log.debug('ArticleBoxController'); 13 $log.debug('ArticleBoxController');
14 14
15 var vm = this; 15 var vm = this;
16 - vm.ArticleService = ArticleService;  
17 - vm.$scope = $scope;  
18 vm.$state = $state; 16 vm.$state = $state;
19 - vm.Slug = Slug;  
20 vm.$log = $log; 17 vm.$log = $log;
21 18
22 vm.init(); 19 vm.init();
@@ -26,24 +23,19 @@ @@ -26,24 +23,19 @@
26 var vm = this; 23 var vm = this;
27 24
28 if(!vm.article.slug){ 25 if(!vm.article.slug){
29 - vm.article.slug = vm.Slug.slugify(vm.article.title); 26 + throw { name: 'NotDefined', message: 'The attribute "slug" is undefined.'};
30 } 27 }
31 28
32 if(!vm.category){ 29 if(!vm.category){
33 - vm.category = vm.article.categories[0]; 30 + throw { name: 'NotDefined', message: 'The attribute "category" is undefined.'};
34 } 31 }
35 32
36 - if(!vm.banner && vm.article.image){  
37 - vm.banner = { 33 + if(!vm.image && vm.article.image){
  34 + vm.image = {
38 src: $rootScope.basePath + vm.article.image.url, 35 src: $rootScope.basePath + vm.article.image.url,
39 alt: 'Imagem de destaque do conteúdo' 36 alt: 'Imagem de destaque do conteúdo'
40 }; 37 };
41 } 38 }
42 -  
43 - // if(vm.article.color && !vm.article.bgColor){  
44 - // // 15% more darker  
45 - // vm.article.colorDarker = window.ColorLuminance(vm.article.color, 0.15);  
46 - // }  
47 }; 39 };
48 40
49 ArticleBoxController.prototype.showContent = function () { 41 ArticleBoxController.prototype.showContent = function () {
@@ -60,7 +52,8 @@ @@ -60,7 +52,8 @@
60 restrict: 'E', 52 restrict: 'E',
61 templateUrl: 'app/components/article-box/article-box.html', 53 templateUrl: 'app/components/article-box/article-box.html',
62 scope: { 54 scope: {
63 - article: '=' 55 + article: '=',
  56 + category: '='
64 }, 57 },
65 controller: ArticleBoxController, 58 controller: ArticleBoxController,
66 controllerAs: 'vm', 59 controllerAs: 'vm',
src/app/components/article-box/article-box.html
1 <article class="article-box" ng-click="vm.showContent()" ng-class="vm.category.slug"> 1 <article class="article-box" ng-click="vm.showContent()" ng-class="vm.category.slug">
2 <div> 2 <div>
3 - <h2 class="article-box--category">{{vm.category.name}}</h2> 3 + <h2 class="article-box--category">{{ ::vm.category.name }}</h2>
4 <div class="article-box--image-wrapper"> 4 <div class="article-box--image-wrapper">
5 - <!-- <img class="article-box--image img-responsive" ng-src="{{vm.banner.src}}" alt="{{vm.banner.alt}}" /> -->  
6 - <div class="article-box--image" ng-style="{'background-image':'url( {{vm.banner.src}} )'}"></div> 5 + <div class="article-box--image" ng-style="{ 'background-image' : 'url({{ vm.image.src }})' }"></div>
7 </div> 6 </div>
8 <div class="article-box--title"> 7 <div class="article-box--title">
9 <h1>{{::vm.article.title}}</h1> 8 <h1>{{::vm.article.title}}</h1>
src/app/components/article-grid/article-grid.directive.js
@@ -9,7 +9,7 @@ @@ -9,7 +9,7 @@
9 function articleGrid() { 9 function articleGrid() {
10 10
11 /** @ngInject */ 11 /** @ngInject */
12 - function ArticleGridController($scope, $rootScope, $element, ArticleService, $location, $filter, $log) { 12 + function ArticleGridController($scope, $rootScope, $element, $location, $filter, $log) {
13 $log.debug('ArticleGridController'); 13 $log.debug('ArticleGridController');
14 14
15 // alias 15 // alias
@@ -19,7 +19,6 @@ @@ -19,7 +19,6 @@
19 vm.$scope = $scope; 19 vm.$scope = $scope;
20 vm.$rootScope = $rootScope; 20 vm.$rootScope = $rootScope;
21 vm.$element = $element; 21 vm.$element = $element;
22 - vm.ArticleService = ArticleService;  
23 vm.$location = $location; 22 vm.$location = $location;
24 vm.$filter = $filter; 23 vm.$filter = $filter;
25 vm.$log = $log; 24 vm.$log = $log;
@@ -27,280 +26,24 @@ @@ -27,280 +26,24 @@
27 26
28 // initialization 27 // initialization
29 vm.init(); 28 vm.init();
  29 + vm.attachListeners();
30 } 30 }
31 31
32 ArticleGridController.prototype.init = function() { 32 ArticleGridController.prototype.init = function() {
33 - var vm = this;  
34 -  
35 - vm.articles = null;  
36 - vm.filtredArticleList = null;  
37 - vm.categories = null;  
38 -  
39 - vm.orderCriteries = [  
40 - { label: 'Título', name: 'titulo' },  
41 - { label: 'Tema', name: 'tema' },  
42 - { label: 'Aleatório', name: 'aleatorio' }  
43 - ];  
44 -  
45 - vm.search = vm.$location.search();  
46 -  
47 - // Add initial values for the filter  
48 - vm.query = (vm.search && vm.search.filtro) ? vm.search.filtro : null;  
49 - vm.limitTo = (vm.search && vm.search.limite) ? parseInt(vm.search.limite, 10) : vm.defaultLimit;  
50 - vm.orderCriteria = (vm.search && vm.search.ordem) ? { name: vm.search.ordem } : null;  
51 - vm.reverse = (vm.search && vm.search.reverso) ? true : false;  
52 -  
53 - // vm.selectedCategory = (vm.search && vm.search.tema) ? vm.getCategoryBySlug(vm.search.tema) : null;  
54 - if (vm.search && vm.search.tema) {  
55 - var slug = vm.search.tema;  
56 - vm.ArticleService.getCategoryBySlug(slug, function(category){  
57 - vm.selectedCategory = category;  
58 - }, function(error){  
59 - vm.$log.error('Error when try to "getCategoryBySlug"', error);  
60 - });  
61 - }  
62 -  
63 - if (!angular.equals({}, vm.search)) {  
64 - var $el = vm.$element;  
65 - angular.element('body').animate({scrollTop: $el.offset().top}, 'slow');  
66 - }  
67 -  
68 - vm.loadData(function(){  
69 - vm.filtredArticleList = vm.getFiltredArticles();  
70 - });  
71 -  
72 - vm.attachListeners(); 33 + // var vm = this;
  34 + // vm.programs = null; // scope var
73 }; 35 };
74 36
75 ArticleGridController.prototype.attachListeners = function() { 37 ArticleGridController.prototype.attachListeners = function() {
76 - var vm = this;  
77 -  
78 - // update window location params  
79 - vm.$scope.$on('change-selectedCategory', function(event, selectedCategory){  
80 - vm.selectedCategory = selectedCategory;  
81 - });  
82 -  
83 - vm.$scope.$watch('vm.query', function(newValue/*, oldValue*/) {  
84 - vm.search.filtro = newValue ? newValue : null;  
85 - vm.$location.search('filtro', vm.search.filtro);  
86 - if(vm.search.filtro){  
87 - vm.limitTo = vm.articles.length;  
88 - }else{  
89 - vm.limitTo = vm.defaultLimit;  
90 - }  
91 - vm.filtredArticleList = vm.getFiltredArticles();  
92 - });  
93 -  
94 - vm.$scope.$watch('vm.limitTo', function(newValue/*, oldValue*/) {  
95 - vm.search.limite = (newValue && newValue !== vm.defaultLimit) ? newValue : null;  
96 - vm.$location.search('limite', vm.search.limite);  
97 - vm.filtredArticleList = vm.getFiltredArticles();  
98 - });  
99 -  
100 - vm.$scope.$watch('vm.selectedCategory', function(newValue/*, oldValue*/) {  
101 - vm.search.tema = newValue ? newValue.slug : null;  
102 - vm.$location.search('tema', vm.search.tema);  
103 - if(vm.search.tema){  
104 - vm.limitTo = vm.articles.length;  
105 - }else{  
106 - vm.limitTo = vm.defaultLimit;  
107 - }  
108 - vm.filtredArticleList = vm.getFiltredArticles();  
109 - });  
110 -  
111 - vm.$scope.$watch('vm.orderCriteria', function(newValue/*, oldValue*/) {  
112 - vm.search.ordem = (newValue && newValue.name) ? newValue.name : null;  
113 - vm.$location.search('ordem', vm.search.ordem);  
114 - vm.filtredArticleList = vm.getFiltredArticles();  
115 - });  
116 -  
117 - vm.$scope.$watch('vm.reverse', function(newValue/*, oldValue*/) {  
118 - vm.search.reverso = newValue ? newValue : null;  
119 - vm.$location.search('reverso', vm.search.reverso);  
120 - vm.filtredArticleList = vm.getFiltredArticles();  
121 - });  
122 -  
123 - };  
124 - ArticleGridController.prototype.loadData = function(cb) {  
125 - var vm = this;  
126 -  
127 - var articlesLoaded = false;  
128 - var categoriesLoaded = false;  
129 -  
130 - vm.ArticleService.getPrograms(function(programs){  
131 - vm.articles = programs;  
132 - articlesLoaded = true;  
133 - endLoad();  
134 - });  
135 -  
136 - vm.ArticleService.getCategories(function(categories){  
137 - vm.categories = categories;  
138 - categoriesLoaded = true;  
139 - endLoad();  
140 - });  
141 -  
142 - function endLoad () {  
143 - if(articlesLoaded && categoriesLoaded){  
144 - cb();  
145 - }  
146 - }  
147 - };  
148 -  
149 - ArticleGridController.prototype.resetFilterValues = function() {  
150 - var vm = this;  
151 -  
152 - vm.query = null;  
153 - vm.limitTo = vm.defaultLimit;  
154 - vm.selectedCategory = null;  
155 - vm.orderCriteria = null;  
156 - };  
157 -  
158 - ArticleGridController.prototype.getIconClasses = function(category) {  
159 - var vm = this;  
160 -  
161 - vm.$log.debug('[TODO] getIconClasses of category:', category);  
162 - return 'glyphicon glyphicon-exclamation-sign';  
163 - };  
164 -  
165 - ArticleGridController.prototype.getCategoryBySlug = function(categorySlug) {  
166 - var vm = this;  
167 - var result = null;  
168 -  
169 - angular.forEach(vm.categories, function(value/*, key*/) {  
170 - if (value.slug === categorySlug) {  
171 - result = value;  
172 - }  
173 - });  
174 -  
175 - return result;  
176 - };  
177 -  
178 - ArticleGridController.prototype.showAll = function($event) {  
179 - var vm = this;  
180 -  
181 - $event.stopPropagation();  
182 -  
183 - vm.resetFilterValues();  
184 - vm.limitTo = vm.articles.length;  
185 - };  
186 -  
187 - ArticleGridController.prototype.getFiltredArticles = function() {  
188 - var vm = this;  
189 -  
190 - if(!vm.articles){  
191 - vm.$log.warn('No articles loaded yet. Abort.');  
192 - return null;  
193 - }  
194 -  
195 - var input = vm.articles;  
196 - var output = input;  
197 - var query = vm.query;  
198 - var selectedCategory = vm.selectedCategory;  
199 - var orderCriteria = vm.orderCriteria ? vm.orderCriteria : { name : 'aleatorio'};  
200 - var filter = vm.$filter('filter');  
201 - var orderBy = vm.$filter('orderBy');  
202 - var limitTo = vm.$filter('limitTo');  
203 - var limit = vm.limitTo ? vm.limitTo : 4;  
204 -  
205 - if (selectedCategory) {  
206 - output = _filterByCategory(output, selectedCategory);  
207 - }  
208 -  
209 - if (query) {  
210 - output = filter(output, query, false);  
211 - }  
212 -  
213 - switch (orderCriteria.name) {  
214 - case 'titulo':  
215 - output = orderBy(output, 'title', vm.reverse);  
216 - break;  
217 - case 'tema':  
218 - output = orderBy(output, 'categories[0].name', vm.reverse);  
219 - break;  
220 - case 'more_participants':  
221 - vm.$log.info('Criteria not handled yet: ', orderCriteria);  
222 - break;  
223 - case 'aleatorio':  
224 - // shuffling  
225 - // if (!vm._isShuffled){  
226 - output = vm.filterShuffle(output);  
227 - // vm._isShuffled = true;  
228 - // }  
229 -  
230 - if (vm.reverse) {  
231 - output = output.slice().reverse();  
232 - }  
233 -  
234 - break;  
235 - default:  
236 - vm.$log.warn('Criteria not matched: ', orderCriteria);  
237 - break;  
238 - }  
239 -  
240 - output = limitTo(output, limit);  
241 -  
242 - return output;  
243 - };  
244 -  
245 - ArticleGridController.prototype.filterShuffle = function(input) {  
246 - var result = [];  
247 - var resultByCategory = {};  
248 -  
249 - // divide by categories  
250 - for (var i = 0; i < input.length; i++) {  
251 - var program = input[i];  
252 - var categorySlug = program.categories[0].slug;  
253 -  
254 - if (!resultByCategory[categorySlug]) {  
255 - resultByCategory[categorySlug] = [];  
256 - }  
257 -  
258 - resultByCategory[categorySlug].push(program);  
259 - }  
260 -  
261 - // shuffle each array  
262 - var prop = null;  
263 - var categoryWithPrograms = null;  
264 - for (prop in resultByCategory) {  
265 - if (resultByCategory.hasOwnProperty(prop)) {  
266 - categoryWithPrograms = resultByCategory[prop];  
267 - resultByCategory[prop] = shuffle(categoryWithPrograms);  
268 - }  
269 - }  
270 -  
271 - // Concat all into result array  
272 - // > while has program at Lists on resultByCategory  
273 - var hasProgram = true;  
274 - while (hasProgram) {  
275 -  
276 - var foundProgram = false;  
277 - // each categoryList with array of program  
278 - prop = null;  
279 - categoryWithPrograms = null;  
280 - for (prop in resultByCategory) {  
281 -  
282 - if (resultByCategory.hasOwnProperty(prop)) {  
283 - categoryWithPrograms = resultByCategory[prop];  
284 -  
285 - if (categoryWithPrograms.length > 0) {  
286 - var pivotProgram = categoryWithPrograms.pop();  
287 - result.push(pivotProgram);  
288 - foundProgram = true;  
289 - }  
290 - }  
291 - }  
292 -  
293 - if (!foundProgram) {  
294 - hasProgram = false;  
295 - }  
296 - }  
297 -  
298 - return result; 38 + // var vm = this;
299 }; 39 };
300 40
301 var directive = { 41 var directive = {
302 restrict: 'E', 42 restrict: 'E',
303 templateUrl: 'app/components/article-grid/article-grid.html', 43 templateUrl: 'app/components/article-grid/article-grid.html',
  44 + scope: {
  45 + articles: '='
  46 + },
304 controller: ArticleGridController, 47 controller: ArticleGridController,
305 controllerAs: 'vm', 48 controllerAs: 'vm',
306 bindToController: true 49 bindToController: true
@@ -308,44 +51,4 @@ @@ -308,44 +51,4 @@
308 51
309 return directive; 52 return directive;
310 } 53 }
311 -  
312 - function _filterByCategory (input, category) {  
313 - input = input || [];  
314 -  
315 - if (!category) {  
316 - // no filter  
317 - return input;  
318 - }  
319 -  
320 - var out = [];  
321 - for (var i = 0; i < input.length; i++) {  
322 - var program = input[i];  
323 - if (program.categories[0].slug === category.slug) {  
324 - out.push(program);  
325 - }  
326 - }  
327 -  
328 - return out;  
329 - }  
330 -  
331 - // -> Fisher–Yates shuffle algorithm  
332 - function shuffle (array) {  
333 - var currentIndex = array.length, temporaryValue, randomIndex ;  
334 -  
335 - // While there remain elements to shuffle...  
336 - while (0 !== currentIndex) {  
337 -  
338 - // Pick a remaining element...  
339 - randomIndex = Math.floor(Math.random() * currentIndex);  
340 - currentIndex -= 1;  
341 -  
342 - // And swap it with the current element.  
343 - temporaryValue = array[currentIndex];  
344 - array[currentIndex] = array[randomIndex];  
345 - array[randomIndex] = temporaryValue;  
346 - }  
347 -  
348 - return array;  
349 - }  
350 -  
351 })(); 54 })();
src/app/components/article-grid/article-grid.html
1 -<article class="article-grid">  
2 - <header class="header">  
3 - <h2>Conheça os programas <span class="small">({{vm.filtredArticleList.length}}/{{vm.articles.length}})</span></h2>  
4 - <button type="button" class="btn btn-link" ng-click="vm.showAll($event)">  
5 - <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span> Ver todos os {{vm.articles.length}} programas  
6 - </button>  
7 - </header>  
8 - <div>  
9 - <div class="col-sm-12">  
10 - <aside class="form-inline">  
11 - <div class="row">  
12 - <div class="col-xs-6 col-sm-7 col-md-9">  
13 - <label for="articleQueryFilter" class="control-label sr-only">Filtrar programas:</label>  
14 - <input id="articleQueryFilter" type="search" class="form-control" ng-model="vm.query" placeholder="Filtrar programas" aria-label="Filtrar programas" >  
15 - </div>  
16 -  
17 - <!-- <label for="selectCategoryFilter" class="control-label sr-only">Filtrar por tema:</label>  
18 - <select id="selectCategoryFilter" name="selectCategoryFilter" class="form-control" ng-model="vm.categoryFilter" ng-options="category.name for category in vm.categories track by category.slug">  
19 - <option value="">-- Filtrar por tema --</option>  
20 - </select> -->  
21 -  
22 - <div class="col-xs-6 col-sm-5 col-md-3">  
23 - <label for="articleOrderByFilter" class="control-label sr-only">Ordernar por:</label>  
24 - <select id="articleOrderByFilter" name="articleOrderByFilter" class="form-control pull-right" ng-model="vm.orderCriteria" ng-options="orderCriteria.label for orderCriteria in vm.orderCriteries">  
25 - <option value="">-- Ordernar por: --</option>  
26 - </select>  
27 - </div>  
28 - <!-- <div class="checkbox">  
29 - <label>  
30 - <input type="checkbox" ng-model="vm.reverse">  
31 - Reverso  
32 - </label>  
33 - </div> -->  
34 -  
35 - <!-- <input id="articleLimitFilter" type="number" class="form-control input-sm" size="4" step="2" ng-model="vm.limitTo" aria-label="Limitar" >  
36 - <label for="articleLimitFilter" class="control-label">Limite</label> -->  
37 -  
38 - </div>  
39 - </aside>  
40 - </div>  
41 -  
42 - <div ng-repeat="article in vm.filtredArticleList as results">  
43 - <article-box article="article" class="col-xs-12 col-sm-6"></article-box>  
44 - <div ng-if="$odd" class="clearfix"></div>  
45 - </div>  
46 - <div class="animate-repeat" ng-if="results.length == 0">  
47 - Nenhum programa encontrado.  
48 - </div> 1 +<div class="article-grid">
  2 + <div ng-repeat="article in vm.articles as results">
  3 + <article-box article="article" category="article.categories[0]" class="col-xs-12 col-sm-6"></article-box>
  4 + <div ng-if="$odd" class="clearfix"></div>
49 </div> 5 </div>
50 -</article> 6 + <div class="animate-repeat" ng-if="results.length == 0">
  7 + Nenhum programa encontrado.
  8 + </div>
  9 +</div>
src/app/components/article-grid/article-grid.scss
1 .article-grid { 1 .article-grid {
2 - .header {  
3 - position: relative;  
4 - height: 40px;  
5 - margin-bottom: 10px;  
6 -  
7 - button {  
8 - position: absolute;  
9 - right: 0;  
10 - top: 2px;  
11 - }  
12 - }  
13 -  
14 - .form-inline {  
15 - input,  
16 - select {  
17 - width: 100%;  
18 - }  
19 - }  
20 } 2 }
src/app/components/article-preview/article-preview.directive.js
@@ -9,14 +9,11 @@ @@ -9,14 +9,11 @@
9 function articlePreview($rootScope) { 9 function articlePreview($rootScope) {
10 10
11 /** @ngInject */ 11 /** @ngInject */
12 - function ArticlePreviewController(ArticleService, $scope, $state, Slug, $log) { 12 + function ArticlePreviewController($state, $log) {
13 $log.debug('ArticlePreviewController'); 13 $log.debug('ArticlePreviewController');
14 14
15 var vm = this; 15 var vm = this;
16 - vm.ArticleService = ArticleService;  
17 - vm.$scope = $scope;  
18 vm.$state = $state; 16 vm.$state = $state;
19 - vm.Slug = Slug;  
20 vm.$log = $log; 17 vm.$log = $log;
21 18
22 vm.init(); 19 vm.init();
@@ -26,7 +23,7 @@ @@ -26,7 +23,7 @@
26 var vm = this; 23 var vm = this;
27 24
28 if(!vm.article.slug){ 25 if(!vm.article.slug){
29 - vm.article.slug = vm.Slug.slugify(vm.article.title); 26 + throw { name: 'NotDefined', message: 'The attribute "slug" is undefined.'};
30 } 27 }
31 28
32 if(!vm.category){ 29 if(!vm.category){
src/app/components/article-service/article.service.js 0 → 100644
@@ -0,0 +1,159 @@ @@ -0,0 +1,159 @@
  1 +(function() {
  2 + 'use strict';
  3 +
  4 + angular
  5 + .module('dialoga')
  6 + .factory('ArticleService', ArticleService);
  7 +
  8 + /** @ngInject */
  9 + function ArticleService($http, $q, $rootScope, API, UtilService, Slug, $log) {
  10 + $log.debug('ArticleService');
  11 +
  12 + var service = {
  13 + apiArticles: $rootScope.basePath + '/api/v1/articles/',
  14 + getArticleById: getArticleById,
  15 + getArticleBySlug: getArticleBySlug,
  16 + getCategories: getCategories,
  17 + getCategoryBySlug: getCategoryBySlug,
  18 + getTopics: getTopics,
  19 + getTopicById: getTopicById,
  20 + getProposals: getProposals,
  21 + getProposalsByTopicId: getProposalsByTopicId,
  22 + searchTopics: searchTopics,
  23 + searchProposals: searchProposals
  24 + };
  25 +
  26 + return service;
  27 +
  28 + function _getArticleById (articleId, params, cbSuccess, cbError) {
  29 +
  30 + var url = service.apiArticles + articleId;
  31 + var paramsExtended = angular.extend({}, params);
  32 +
  33 + UtilService.get(url, {params: paramsExtended}).then(function(data){
  34 + cbSuccess(data);
  35 + }).catch(function(error){
  36 + cbError(error);
  37 + });
  38 + }
  39 +
  40 + function getArticleById (articleId, params, cbSuccess, cbError) {
  41 + _getArticleById(articleId, params, cbSuccess, cbError);
  42 + }
  43 +
  44 + function getArticleBySlug (/*slug, params, cbSuccess, cbError*/) {
  45 + throw { name: 'NotImplementedYet', message: 'The service "getArticleBySlug" is not implemented yet.'};
  46 + }
  47 +
  48 + function getCategories (articleId, cbSuccess, cbError) {
  49 + // Ex.: /api/v1/articles/103358?fields=
  50 +
  51 + var url = service.apiArticles + articleId;
  52 +
  53 + UtilService.get(url, {params: {
  54 + 'fields[]': ['id', 'categories']
  55 + }}).then(function(data){
  56 + cbSuccess(data);
  57 + }).catch(function(error){
  58 + cbError(error);
  59 + });
  60 + }
  61 +
  62 + function getCategoryBySlug () {
  63 + throw { name: 'NotImplementedYet', message: 'The service "getArticleBySlug" is not implemented yet.'};
  64 + }
  65 +
  66 + function getTopics (cbSuccess, cbError) {
  67 + // Ex.: /api/v1/articles/103358/children?fields=
  68 +
  69 + var url = service.apiArticles + API.articleId.home + '/children';
  70 +
  71 + UtilService.get(url, {params: {
  72 + 'fields[]': ['id', 'title', 'slug', 'abstract', 'categories', 'setting', 'children_count', 'hits']
  73 + }}).then(function(data){
  74 + cbSuccess(data);
  75 + }).catch(function(error){
  76 + cbError(error);
  77 + });
  78 + }
  79 +
  80 + function getTopicById (topicId, cbSuccess, cbError) {
  81 + // Ex.: /api/v1/articles/103358/children/121521?fields=
  82 +
  83 + // var url = service.apiArticles + API.articleId.home + '/children/' + topicId; // dont need to chain
  84 + var url = service.apiArticles + topicId;
  85 +
  86 + UtilService.get(url, {params: {
  87 + 'fields[]': ['id', 'title', 'body', 'slug', 'abstract', 'categories', 'setting', 'children_count', 'hits']
  88 + }}).then(function(data){
  89 + cbSuccess(data);
  90 + }).catch(function(error){
  91 + cbError(error);
  92 + });
  93 + }
  94 +
  95 + function getProposals (params, cbSuccess, cbError) {
  96 + // Ex.: /api/v1/articles/103358?fields=
  97 +
  98 + var url = service.apiArticles + API.articleId.home;
  99 +
  100 + var paramsExtended = angular.extend({
  101 + 'fields[]': ['id', 'title', 'slug', 'abstract', 'categories', 'setting', 'children_count', 'hits'],
  102 + 'content_type':'ProposalsDiscussionPlugin::Proposals'
  103 + }, params);
  104 +
  105 + UtilService.get(url, {params: paramsExtended}).then(function(data){
  106 + cbSuccess(data);
  107 + }).catch(function(error){
  108 + cbError(error);
  109 + });
  110 + }
  111 +
  112 + function getProposalsByTopicId (topicId, params, cbSuccess, cbError) {
  113 + var url = service.apiArticles + topicId;
  114 +
  115 + var paramsExtended = angular.extend({
  116 + 'fields[]': ['id', 'title', 'abstract', 'children', 'children_count'],
  117 + 'content_type':'ProposalsDiscussionPlugin::Proposals'
  118 + }, params);
  119 +
  120 + UtilService.get(url, {params: paramsExtended}).then(function(data){
  121 + cbSuccess(data);
  122 + }).catch(function(error){
  123 + cbError(error);
  124 + });
  125 + }
  126 +
  127 + function getRandomProposal (cbSuccess, cbError) {}
  128 +
  129 + function searchTopics (params, cbSuccess, cbError) {
  130 + // Ex.: /api/v1/search/article?type=ProposalsDiscussionPlugin::Topic&query=cisternas
  131 + var url = '/api/v1/search/article';
  132 + var paramsExtended = angular.extend({
  133 + 'fields[]': ['id', 'title', 'slug', 'abstract', 'categories', 'setting', 'children_count', 'hits'],
  134 + 'type': 'ProposalsDiscussionPlugin::Topic'
  135 + }, params);
  136 +
  137 + UtilService.get(url, {params: paramsExtended}).then(function(data){
  138 + cbSuccess(data);
  139 + }).catch(function(error){
  140 + cbError(error);
  141 + });
  142 + }
  143 +
  144 + function searchProposals (params, cbSuccess, cbError) {
  145 + // Ex.: /api/v1/search/article?type=ProposalsDiscussionPlugin::Proposal&query=cisternas
  146 + var url = '/api/v1/search/article';
  147 + var paramsExtended = angular.extend({
  148 + 'fields[]': ['id', 'title', 'slug', 'abstract', 'categories', 'setting', 'children_count', 'hits'],
  149 + 'type': 'ProposalsDiscussionPlugin::Proposal'
  150 + }, params);
  151 +
  152 + UtilService.get(url, {params: paramsExtended}).then(function(data){
  153 + cbSuccess(data);
  154 + }).catch(function(error){
  155 + cbError(error);
  156 + });
  157 + }
  158 + }
  159 +})();
src/app/components/article-service/article.service.spec.js 0 → 100644
@@ -0,0 +1,67 @@ @@ -0,0 +1,67 @@
  1 +(function() {
  2 + 'use strict';
  3 +
  4 + describe('article services', function() {
  5 + var ArticleService, httpBackend;
  6 +
  7 + beforeEach(module('dialoga'));
  8 +
  9 + beforeEach(inject(function(_ArticleService_, $httpBackend) {
  10 + ArticleService = _ArticleService_;
  11 + httpBackend = $httpBackend;
  12 + }));
  13 +
  14 + it('should return the main article', function() {
  15 + var url = 'http://login.dialoga.gov.br/api/v1/articles/103358?fields=id,children,categories,abstract,title,image,url,setting,position&private_token=null';
  16 + httpBackend.whenGET(url).respond({
  17 + 'article':{'id':103358,'abstract':'\u003Cp style=\"text-align: center;\"\u003E\u003Ciframe src=\"https://www.youtube.com/embed/kpAdrO-emV0?rel=0\u0026amp;showinfo=0\u0026amp;iv_load_policy=3\u0026amp;controls=1\" style=\"max-width: 1000px; left: 5%;\" width=\"275\" height=\"200\"\u003E\u003C/iframe\u003E\u003C/p\u003E','title':'Dialoga Brasil','categories':[{'name':'Sa\u00fade','id':180,'slug':'saude','image':null},{'name':'Seguran\u00e7a P\u00fablica','id':182,'slug':'seguranca-publica','image':null},{'name':'Educa\u00e7\u00e3o','id':181,'slug':'educacao','image':null},{'name':'Redu\u00e7\u00e3o da Pobreza','id':183,'slug':'reducao-da-pobreza','image':null}],'image':null,'setting':{'custom_body_label':'Corpo','phase':'proposals','allow_topics':true,'moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Leandro Nunes dos Santos','moderate_proposals':true,'allow_members_to_edit':false},'position':null,'children':[{'id':103644,'abstract':'\u003Cp\u003EUm caminho de oportunidades com o Enem: Sisu, Prouni, Fies, Ci\u00eancia sem Fronteiras\u003C/p\u003E','title':'Ensino Superior','categories':[{'name':'Educa\u00e7\u00e3o','id':181,'slug':'educacao','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0128/enem.jpg'},'setting':{'color':'#cfe2f3','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':9},{'id':103673,'abstract':'\u003Cp\u003EA melhor escolha \u00e9 se informar.\u003C/p\u003E','title':'Incentivo ao Parto Normal','categories':[{'name':'Sa\u00fade','id':180,'slug':'saude','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0092/parto-normal.jpg'},'setting':{'color':'#ff0000','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':6},{'id':103397,'abstract':'\u003Cp\u003ERenda, inclus\u00e3o produtiva e acesso a servi\u00e7os.\u003C/p\u003E','title':'Brasil Sem Mis\u00e9ria','categories':[{'name':'Redu\u00e7\u00e3o da Pobreza','id':183,'slug':'reducao-da-pobreza','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0116/bsm_redim.jpg'},'setting':{'color':'','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':18},{'id':103379,'abstract':'\u003Cp\u003EResgate e atendimento 24 horas, sete dias da semana.\u003C/p\u003E','title':'SAMU 192 e UPAs','categories':[{'name':'Sa\u00fade','id':180,'slug':'saude','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0060/SAMU.jpg'},'setting':{'color':'#45818e','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':4},{'id':103521,'abstract':'\u003Cp\u003EMais atendimento nos munic\u00edpios, mais sa\u00fade para quem mais precisa.\u003C/p\u003E','title':'Mais M\u00e9dicos','categories':[{'name':'Sa\u00fade','id':180,'slug':'saude','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0025/Mais_M_dicos.jpg'},'setting':{'color':'#ffe599','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':1},{'id':103390,'abstract':'\u003Cp\u003EPreven\u00e7\u00e3o, tratamento e enfrentamento ao tr\u00e1fico.\u003C/p\u003E','title':'Crack, \u00e9 poss\u00edvel vencer!','categories':[{'name':'Seguran\u00e7a P\u00fablica','id':182,'slug':'seguranca-publica','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0104/crack.jpg'},'setting':{'color':'#00ff00','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':14},{'id':103592,'abstract':'\u003Cp\u003EGarantir acesso \u00e0 prote\u00e7\u00e3o social.\u003C/p\u003E','title':'Assist\u00eancia Social','categories':[{'name':'Redu\u00e7\u00e3o da Pobreza','id':183,'slug':'reducao-da-pobreza','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0122/assistencia_social.jpg'},'setting':{'color':'#a61c00','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':19},{'id':103426,'abstract':'\u003Cp\u003EDa sa\u00fade se cuida todos os dias.\u003C/p\u003E','title':'Vida saud\u00e1vel','categories':[{'name':'Sa\u00fade','id':180,'slug':'saude','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0046/vida_saudavel.jpg'},'setting':{'color':'#d9d2e9','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':7},{'id':103695,'abstract':'\u003Cp\u003ENovo modelo de atua\u00e7\u00e3o em Seguran\u00e7a P\u00fablica.\u003C/p\u003E','title':'Seguran\u00e7a P\u00fablica Integrada','categories':[{'name':'Seguran\u00e7a P\u00fablica','id':182,'slug':'seguranca-publica','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0152/policiaintegrada.jpg'},'setting':{'color':'#ff00ff','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':13},{'id':103663,'abstract':'\u003Cp\u003EMais educa\u00e7\u00e3o profissional e tecnol\u00f3gica, mais desenvolvimento\u003C/p\u003E','title':'Ensino T\u00e9cnico','categories':[{'name':'Educa\u00e7\u00e3o','id':181,'slug':'educacao','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0134/Ensino_tecnico.jpg'},'setting':{'color':'#d0e0e3','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':10},{'id':103472,'abstract':'\u003Cp\u003EPol\u00edcia Federal, Pol\u00edcia Rodovi\u00e1ria Federal e For\u00e7a Nacional de Seguran\u00e7a P\u00fablica.\u003C/p\u003E','title':'For\u00e7as Federais de Seguran\u00e7a','categories':[{'name':'Seguran\u00e7a P\u00fablica','id':182,'slug':'seguranca-publica','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0031/federais2.png'},'setting':{'color':'','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':16},{'id':103612,'abstract':'\u003Cp\u003EGarantir \u00e1gua para beber e produzir.\u003C/p\u003E','title':'Cisternas','categories':[{'name':'Redu\u00e7\u00e3o da Pobreza','id':183,'slug':'reducao-da-pobreza','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0039/cisterna_redim.jpg'},'setting':{'color':'#0000ff','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':20},{'id':103442,'abstract':'\u003Cp\u003EComplemento \u00e0 renda e acompanhamento em educa\u00e7\u00e3o e sa\u00fade.\u003C/p\u003E','title':'Bolsa Fam\u00edlia','categories':[{'name':'Redu\u00e7\u00e3o da Pobreza','id':183,'slug':'reducao-da-pobreza','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0013/bolsa_familia_redim.jpg'},'setting':{'color':'#ff9900','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':17},{'id':103507,'abstract':'\u003Cp\u003ETecnologia a servi\u00e7o da seguran\u00e7a do cidad\u00e3o.\u003C/p\u003E','title':'Sinesp','categories':[{'name':'Seguran\u00e7a P\u00fablica','id':182,'slug':'seguranca-publica','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0098/sinesp.png'},'setting':{'color':'#00ff00','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':12},{'id':103683,'abstract':'\u003Cp\u003ESa\u00fade n\u00e3o tem pre\u00e7o.\u003C/p\u003E','title':'Aqui tem Farm\u00e1cia Popular','categories':[{'name':'Sa\u00fade','id':180,'slug':'saude','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0019/saude_nao_tem_preco.jpg'},'setting':{'color':'#e69138','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':5},{'id':103457,'abstract':'\u003Cp\u003EA\u00e7\u00e3o conjunta e coopera\u00e7\u00e3o transfronteiri\u00e7a.\u003C/p\u003E','title':'Prote\u00e7\u00e3o das Fronteiras','categories':[{'name':'Seguran\u00e7a P\u00fablica','id':182,'slug':'seguranca-publica','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0110/fronteira_redim.jpg'},'setting':{'color':'#a64d79','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':15},{'id':103494,'abstract':'\u003Cp\u003EDa Educa\u00e7\u00e3o Infantil ao Ensino M\u00e9dio.\u003C/p\u003E','title':'Educa\u00e7\u00e3o B\u00e1sica','categories':[{'name':'Educa\u00e7\u00e3o','id':181,'slug':'educacao','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0076/Educa__o_B_sica.jpg'},'setting':{'color':'#fce5cd','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':8},{'id':103359,'abstract':'\u003Cp\u003EAcesso a exames e consultas com especialistas.\u003C/p\u003E','title':'Mais Especialidades','categories':[{'name':'Sa\u00fade','id':180,'slug':'saude','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0083/mais_especialidades1.png'},'setting':{'color':'#ea9999','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':2},{'id':103485,'abstract':'\u003Cp\u003ECaminho para uma educa\u00e7\u00e3o de qualidade.\u003C/p\u003E','title':'Valoriza\u00e7\u00e3o dos Professores','categories':[{'name':'Educa\u00e7\u00e3o','id':181,'slug':'educacao','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0140/valorizacao_professor.jpg'},'setting':{'color':'#ffff00','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':11},{'id':103416,'abstract':'\u003Cp\u003EEstrutura adequada para atender melhor a popula\u00e7\u00e3o na aten\u00e7\u00e3o b\u00e1sica.\u003C/p\u003E','title':'Melhorar os Postos de Sa\u00fade','categories':[{'name':'Sa\u00fade','id':180,'slug':'saude','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0053/requalif_redim.jpg'},'setting':{'color':'#cc4125','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':3}]}});
  18 +
  19 + ArticleService.getHome(function(result){
  20 + expect(result.article).toBeDefined();
  21 + expect(result.article.title).toEqual('Dialoga Brasil');
  22 + expect(result.article.categories).toBeDefined();
  23 + });
  24 +
  25 + httpBackend.flush();
  26 + });
  27 +
  28 + // it('should return a list of articles', function() {
  29 +
  30 + // httpBackend.whenGET('http://login.dialoga.gov.br/api/v1/articles').respond({
  31 + // "articles": [
  32 + // {
  33 + // abstract: "Que exista educação continuada permanente dos profissionais!!",
  34 + // author: null,
  35 + // body: "",
  36 + // categories: [],
  37 + // children: [],
  38 + // created_at: "2015/08/04 16:36:13",
  39 + // end_date: null,
  40 + // hits: 0,
  41 + // id: 120568,
  42 + // image: null,
  43 + // parent: {id: 103379,…},
  44 + // position: null,
  45 + // profile: {identifier: "dialoga", name: "dialoga", id: 19195, created_at: "2015/04/15 09:38:36", image: null},
  46 + // setting: {comment_paragraph_plugin_activate: false, author_name: "estacio"},
  47 + // start_date: null,
  48 + // tag_list: [],
  49 + // title: "article_f4f4601c-0f36-e90e-d01a-9871f0bd126b",
  50 + // votes_against: 0,
  51 + // votes_for: 0,
  52 + // }
  53 + // ]
  54 + // });
  55 +
  56 + // ArticleService.getList().then(function(result) {
  57 + // console.log('result', result);
  58 +
  59 + // expect(result.data.article).toBeDefined();
  60 + // expect(result.data.article.title).toEqual('Dialoga Brasil');
  61 +
  62 + // });
  63 +
  64 + // httpBackend.flush();
  65 + // });
  66 + });
  67 +})();
src/app/components/auth-user/auth-user.directive.js
@@ -42,6 +42,7 @@ @@ -42,6 +42,7 @@
42 AuthUserController.prototype.onClickLogout = function (){ 42 AuthUserController.prototype.onClickLogout = function (){
43 var vm = this; 43 var vm = this;
44 44
  45 + // TODO: emit event?
45 vm.AuthService.logout(); 46 vm.AuthService.logout();
46 }; 47 };
47 48
src/app/components/breadcrumb/breadcrumb.scss
1 .custom-breadcrumb { 1 .custom-breadcrumb {
  2 +
  3 + .breadcrumb {
  4 + background: none;
  5 + padding: 0;
  6 + margin: 0;
  7 + }
  8 +
  9 + .glyphicon {
  10 + color: #1E3E65;;
  11 + border: 1px solid #1E3E65;
  12 + border-radius: 100%;
  13 + width: 23px;
  14 + height: 23px;
  15 + margin: 0;
  16 + padding: 2px 0 0 3px;
  17 + }
  18 +
2 .breadcrumb > li + li:before { 19 .breadcrumb > li + li:before {
3 - content: '>'; 20 + content: '\00BB';
4 } 21 }
5 22
6 .contraste & .breadcrumb { 23 .contraste & .breadcrumb {
src/app/components/breadcrumb/template.html
1 <div class="custom-breadcrumb"> 1 <div class="custom-breadcrumb">
2 <ol class="breadcrumb"> 2 <ol class="breadcrumb">
3 - <li ng-repeat="step in steps | limitTo:(steps.length-1)">  
4 - <a href="{{step.ncyBreadcrumbLink}}" ng-bind-html="step.ncyBreadcrumbLabel"></a>  
5 - </li>  
6 - <li ng-repeat="step in steps | limitTo:-1" class="active">  
7 - <span ng-bind-html="step.ncyBreadcrumbLabel"></span>  
8 - </li> 3 + <li ng-repeat="step in steps | limitTo:(steps.length-1)">
  4 + <a href="{{step.ncyBreadcrumbLink}}" ng-if="$index === 0" ng-class="{'item-home': $index === 0}">
  5 + <span class="glyphicon glyphicon-home" aria-hidden="true"></span>
  6 + </a>
  7 + <a href="{{step.ncyBreadcrumbLink}}" ng-if="$index !== 0" ng-class="{'item-home': $index === 0}" ng-bind-html="step.ncyBreadcrumbLabel"></a>
  8 + </li>
  9 + <li ng-repeat="step in steps | limitTo:-1" class="active">
  10 + <span ng-bind-html="step.ncyBreadcrumbLabel"></span>
  11 + </li>
9 </ol> 12 </ol>
10 </div> 13 </div>
src/app/components/category-list/category-list.directive.js
@@ -9,7 +9,7 @@ @@ -9,7 +9,7 @@
9 function categoryList() { 9 function categoryList() {
10 10
11 /** @ngInject */ 11 /** @ngInject */
12 - function CategoryListController($rootScope, ArticleService, $location, $log) { 12 + function CategoryListController($rootScope, $location, $log) {
13 $log.debug('CategoryListController'); 13 $log.debug('CategoryListController');
14 14
15 // alias 15 // alias
@@ -17,33 +17,15 @@ @@ -17,33 +17,15 @@
17 17
18 // dependencies 18 // dependencies
19 vm.$rootScope = $rootScope; 19 vm.$rootScope = $rootScope;
20 - vm.ArticleService = ArticleService;  
21 vm.$location = $location; 20 vm.$location = $location;
22 vm.$log = $log; 21 vm.$log = $log;
23 - vm.defaultLimit = 6;  
24 22
25 // initialization 23 // initialization
26 vm.init(); 24 vm.init();
27 } 25 }
28 26
29 CategoryListController.prototype.init = function() { 27 CategoryListController.prototype.init = function() {
30 - var vm = this;  
31 -  
32 - vm.selectedCategory = null;  
33 - vm.ArticleService.getCategories(function(categories){  
34 - vm.categories = categories;  
35 -  
36 - });  
37 -  
38 - vm.search = vm.$location.search();  
39 - if (vm.search && vm.search.tema) {  
40 - var slug = vm.search.tema;  
41 - vm.ArticleService.getCategoryBySlug(slug, function(category){  
42 - vm.selectedCategory = category;  
43 - }, function(error){  
44 - vm.$log.error('Error when try to "getCategoryBySlug"', error);  
45 - });  
46 - } 28 + // var vm = this;
47 }; 29 };
48 30
49 CategoryListController.prototype.selectCategory = function(category, $event) { 31 CategoryListController.prototype.selectCategory = function(category, $event) {
@@ -66,6 +48,10 @@ @@ -66,6 +48,10 @@
66 var directive = { 48 var directive = {
67 restrict: 'E', 49 restrict: 'E',
68 templateUrl: 'app/components/category-list/category-list.html', 50 templateUrl: 'app/components/category-list/category-list.html',
  51 + scope: {
  52 + categories: '=',
  53 + selectedCategory: '@'
  54 + },
69 controller: CategoryListController, 55 controller: CategoryListController,
70 controllerAs: 'categoryListCtrl', 56 controllerAs: 'categoryListCtrl',
71 bindToController: true 57 bindToController: true
src/app/components/dialoga-service/dialoga.service.js 0 → 100644
@@ -0,0 +1,293 @@ @@ -0,0 +1,293 @@
  1 +(function() {
  2 + 'use strict';
  3 +
  4 + angular
  5 + .module('dialoga')
  6 + .factory('DialogaService', DialogaService);
  7 +
  8 + /** @ngInject */
  9 + function DialogaService($rootScope, $sce, API, ArticleService, UtilService, Slug, $log) {
  10 + $log.debug('DialogaService');
  11 +
  12 + var service = {
  13 + getHome: getHome,
  14 + getAbout: getAbout,
  15 + getThemes: getThemes,
  16 + getPrograms: getPrograms,
  17 + getProgramBySlug: getProgramBySlug,
  18 + getProgramsRandom: getProgramsRandom,
  19 + getProposals: getProposals,
  20 + getProposalsByTopicId: getProposalsByTopicId,
  21 + getEvents: getEvents,
  22 + getQuestions: getQuestions,
  23 + searchProgram: searchProgram,
  24 + searchProposal: searchProposal,
  25 + };
  26 +
  27 + var CACHE = {};
  28 +
  29 + return service;
  30 +
  31 + function getHome (cbSuccess, cbError) {
  32 + if( !!CACHE.home ){
  33 + cbSuccess(CACHE.home);
  34 + }else{
  35 + // load main content
  36 + ArticleService.getArticleById(API.articleId.home, {
  37 + 'fields[]': ['id','abstract','body','categories','children','children_count','title','image','url']
  38 + }, function (data){
  39 + CACHE.home = data;
  40 +
  41 + _pipeHandleYoutube(data);
  42 + _pipeHandleSlug(data);
  43 + _pipeSetAbout(data);
  44 + _pipeSetThemes(data);
  45 + _pipeSetPrograms(data);
  46 +
  47 + cbSuccess(data);
  48 + }, cbError);
  49 + }
  50 + }
  51 +
  52 + function getAbout (cbSuccess, cbError) {
  53 + if( !!CACHE.about ){
  54 + cbSuccess(CACHE.about);
  55 + }else{
  56 + // load article content
  57 + ArticleService.getArticleById(API.articleId.about, {}, function (article){
  58 + CACHE.about = article;
  59 +
  60 + cbSuccess(CACHE.about);
  61 + }, cbError);
  62 + }
  63 + }
  64 +
  65 + function getThemes (cbSuccess, cbError) {
  66 + if( !!CACHE.themes ){
  67 + cbSuccess(CACHE.themes);
  68 + }else{
  69 + // load main content
  70 + getHome(function(){
  71 + if(!CACHE.hasOwnProperty('themes')){
  72 + throw { name: 'NotFound', message: '"themes" is not defined. "article.categories" was loaded?'};
  73 + }
  74 + cbSuccess(CACHE.themes);
  75 + },cbError);
  76 + }
  77 + }
  78 +
  79 + function getPrograms (cbSuccess, cbError) {
  80 + if( !!CACHE.programs ){
  81 + cbSuccess(CACHE.programs);
  82 + }else{
  83 + // load main content
  84 + getHome(function(){
  85 + if(!CACHE.hasOwnProperty('programs')){
  86 + throw { name: 'NotFound', message: '"programs" is not defined. "article.children" was handled?'};
  87 + }
  88 + cbSuccess(CACHE.programs);
  89 + },cbError);
  90 + }
  91 + }
  92 +
  93 + function getProgramBySlug (slug, cbSuccess, cbError) {
  94 +
  95 + if( !CACHE.programs ){
  96 + getPrograms(_getProgramBySlug, cbError);
  97 + } else {
  98 + _getProgramBySlug();
  99 + }
  100 +
  101 + function _getProgramBySlug(){
  102 + var result = CACHE.programs.filter(function filterProgramBySlug (program) {
  103 + if(angular.equals(program.slug, slug)) {
  104 + return true;
  105 + }
  106 + return false;
  107 + });
  108 +
  109 + cbSuccess(result[0]);
  110 + }
  111 + }
  112 +
  113 + function getProgramsRandom (cbSuccess, cbError) {
  114 + getPrograms(cbSuccess, cbError);
  115 + // TODO: get endpoint for production
  116 + // if( !!CACHE.programsRandom ){
  117 + // cbSuccess(CACHE.programsRandom);
  118 + // }else{
  119 + // // load article content
  120 + // // UtilService.get(API.random_topics, {params: {
  121 + // ArticleService.getArticleById(API.articleId.home, {params: {
  122 + // 'fields[]': [
  123 + // 'id', 'title', 'slug', 'abstract', 'children_count'],
  124 + // 'content_type': 'ProposalsDiscussionPlugin::Topic'
  125 + // }}).then(function(data){
  126 + // CACHE.programsRandom = data;
  127 +
  128 + // cbSuccess(data);
  129 + // }).catch(function(error){
  130 + // cbError(error);
  131 + // });
  132 + // }
  133 + }
  134 +
  135 + function getProposals (param, cbSuccess, cbError) {
  136 + ArticleService.getProposals(param, function (data){
  137 + CACHE.proposals = data;
  138 +
  139 + cbSuccess(CACHE.proposals);
  140 + }, cbError);
  141 + }
  142 +
  143 + function getProposalsByTopicId (topicId, params, cbSuccess, cbError) {
  144 + ArticleService.getProposalsByTopicId(topicId, params, function (data){
  145 + CACHE.proposals = data;
  146 +
  147 + cbSuccess(CACHE.proposals);
  148 + }, cbError);
  149 + }
  150 +
  151 + function getEvents (cbSuccess, cbError) {
  152 + if( !!CACHE.events ){
  153 + cbSuccess(CACHE.events);
  154 + }else{
  155 + // load main content
  156 + getHome(function(){
  157 + if(!CACHE.hasOwnProperty('events')){
  158 + throw { name: 'NotFound', message: '"events" is not defined. "article.categories" was loaded?'};
  159 + }
  160 + cbSuccess(CACHE.events);
  161 + },cbError);
  162 + }
  163 + }
  164 +
  165 + function getQuestions (cbSuccess/*, cbError*/) {
  166 + if( !!CACHE.questions ){
  167 + cbSuccess(CACHE.questions);
  168 + }else{
  169 + // load content
  170 + var questions = [];
  171 +
  172 + CACHE.questions = questions;
  173 + cbSuccess(CACHE.questions);
  174 + }
  175 + }
  176 +
  177 + function searchProgram (cbSuccess, cbError) {}
  178 +
  179 + function searchProposal (cbSuccess, cbError) {}
  180 +
  181 + function _pipeHandleYoutube (data) {
  182 + var abstract = data.article.abstract;
  183 +
  184 + abstract = forceIframeParams(abstract);
  185 + abstract = removeStylefromIframe(abstract);
  186 +
  187 + data.article.abstract = abstract;
  188 +
  189 + data.article.abstractTrusted = $sce.trustAsHtml(abstract);
  190 + }
  191 +
  192 + function _pipeHandleSlug (data) {
  193 + // set slug to article
  194 + if(!data.article.slug){
  195 + data.article.slug = Slug.slugify(data.article.title);
  196 + }
  197 +
  198 + // set slug to programs
  199 + for (var i = data.article.children.length - 1; i >= 0; i--) {
  200 + var program = data.article.children[i];
  201 + if(!program.slug){
  202 + program.slug = Slug.slugify(program.title);
  203 + }
  204 + }
  205 + }
  206 +
  207 + function _pipeSetAbout (data) {
  208 + if(!CACHE.hasOwnProperty('about')){
  209 + CACHE.about = data.article.body;
  210 + }
  211 + }
  212 +
  213 + function _pipeSetThemes (data) {
  214 + if(!CACHE.hasOwnProperty('themes')){
  215 + CACHE.themes = data.article.categories;
  216 + }
  217 +
  218 + _pipeCalcColors(data);
  219 + }
  220 +
  221 + function _pipeSetPrograms (data) {
  222 + if(!CACHE.hasOwnProperty('programs')){
  223 + CACHE.programs = data.article.children;
  224 + CACHE.programs_count = data.article.children_count;
  225 + }
  226 + }
  227 +
  228 + // Calculate color pallet
  229 + function _pipeCalcColors (data) {
  230 + // var darkFactor = 0.15;
  231 + if(data.article.categories){
  232 + // var categories = data.article.categories;
  233 +
  234 + // Handle Category Data
  235 +
  236 + // Handle Category Colors
  237 + // for (var i = categories.length - 1; i >= 0; i--) {
  238 + // var category = categories[i];
  239 + // if(category.color && !category.bgColor){
  240 + // category.colorDarker = $window.ColorLuminance(category.color, 0.15);
  241 + // }
  242 + // };
  243 + }
  244 + }
  245 +
  246 + function forceIframeParams(abstract) {
  247 + var patternIframe = '<iframe src="';
  248 + var indexOfIframe = abstract.indexOf(patternIframe);
  249 +
  250 + if (indexOfIframe === -1) {
  251 + return abstract;
  252 + }
  253 +
  254 + var startSrcUrl = indexOfIframe + patternIframe.length;
  255 + var endSrcUrl = abstract.indexOf('"', startSrcUrl);
  256 + var srcUrl = abstract.substring(startSrcUrl , endSrcUrl);
  257 + var resultUrl = srcUrl;
  258 + var c = (srcUrl.indexOf('?') !== -1) ? '&' : ''; // already have url params. So, append-it
  259 +
  260 + // enable js api
  261 + if (srcUrl.indexOf('enablejsapi=1') === -1) {
  262 + resultUrl += c + 'enablejsapi=1';
  263 + c = '&'; // force to always use '&' after here
  264 + }
  265 +
  266 + // set opaque mode
  267 + if (srcUrl.indexOf('wmode=opaque') === -1) {
  268 + resultUrl += c + 'wmode=opaque';
  269 + // c = '&'; // force to always use '&' after here
  270 + }
  271 +
  272 + abstract = abstract.replace(srcUrl, resultUrl);
  273 +
  274 + return abstract;
  275 + }
  276 +
  277 + function removeStylefromIframe (abstract) {
  278 + var patternIframe = 'style="';
  279 + var indexOfIframe = abstract.indexOf('<iframe');
  280 + var indexOfStyleOnIframe = abstract.indexOf('style="', indexOfIframe);
  281 +
  282 + if (indexOfStyleOnIframe === -1) {
  283 + return abstract;
  284 + }
  285 +
  286 + var startStyleContent = indexOfStyleOnIframe + patternIframe.length;
  287 + var endStyleContent = abstract.indexOf('"', startStyleContent);
  288 + var style = abstract.substring(startStyleContent , endStyleContent);
  289 +
  290 + return abstract.replace(style, '');
  291 + }
  292 + }
  293 +})();
src/app/components/event-list/event-list.html
1 <div class="event-list"> 1 <div class="event-list">
2 - <div class="event-tab--trigger" ng-show="!eventListCtrl.isListVisible" ng-click="eventListCtrl.toggleView()">  
3 - <div class="event-tab--header">  
4 - <div class="event-tab--icon">  
5 - <span class="glyphicon glyphicon-calendar" aria-hidden="true"></span> 2 +
  3 + <section class="color-theme-common-bg">
  4 +
  5 + <div class="container">
  6 + <div class="event-bar--trigger">
  7 + <div class="event-bar--trigger-top">
  8 + <div class="col-sm-6">
  9 + <h1 class="title">
  10 + <span class="glyphicon glyphicon-calendar icon-circle color-theme-common-fg"></span>
  11 + Agenda <b>Dialoga Brasil</b>
  12 + </h1>
  13 + </div>
  14 + <div class="col-sm-6">
  15 + <h2 class="event-bar--trigger-toggle text-right" ng-click="eventListCtrl.toggleView()">
  16 + <span><b>18</b> bate papos <b>agendados</b></span>
  17 + <span class="glyphicon glyphicon-menu-down" aria-hidden="true"></span>
  18 + </h2>
  19 + </div>
  20 + </div>
6 </div> 21 </div>
7 - <div class="event-tab--title">Bate-Papo com ministr@s</div>  
8 </div> 22 </div>
9 - <button class="btn btn-link event-tab--button">  
10 - <span class="event-tab--total-scheduled">18</span>  
11 - <span>bate-papos agendados</span>  
12 - <span class="glyphicon glyphicon-triangle-bottom" aria-hidden="true"></span>  
13 - </button>  
14 - </div> 23 + </section>
15 24
16 - <div class="event-list--panel ng-hide" ng-show="eventListCtrl.isListVisible">  
17 - <div class="event-list--header">  
18 - <div class="event-list--icon">  
19 - <div class="glyphicon glyphicon-calendar" aria-hidden="true"></div>  
20 - </div>  
21 - <h2 class="event-list--title">Bate-papo com ministr@s</h2>  
22 - <div class="event-list--minimize">  
23 - <button type="button" class="btn btn-link" ng-click="eventListCtrl.toggleView()">  
24 - <span>Minimizar</span>  
25 - <span class="glyphicon glyphicon-triangle-top" aria-hidden="true"></span> 25 + <section class="section-table">
  26 + <div class="container">
  27 + <!-- <div class="event-tab--trigger" ng-show="!eventListCtrl.isListVisible" ng-click="eventListCtrl.toggleView()">
  28 + <div class="event-tab--header">
  29 + <div class="event-tab--icon">
  30 + <span class="glyphicon glyphicon-calendar" aria-hidden="true"></span>
  31 + </div>
  32 + <div class="event-tab--title">Bate-Papo com ministr@s</div>
  33 + </div>
  34 + <button class="btn btn-link event-tab--button">
  35 + <span class="event-tab--total-scheduled">18</span>
  36 + <span>bate-papos agendados</span>
  37 + <span class="glyphicon glyphicon-triangle-bottom" aria-hidden="true"></span>
26 </button> 38 </button>
  39 + </div> -->
  40 +
  41 + <div class="event-list--panel ng-hide" ng-show="eventListCtrl.isListVisible">
  42 + <div class="event-list--table-wrapper">
  43 + <div class="table-responsive">
  44 + <table class="table event-list--table">
  45 + <!-- <thead></thead> -->
  46 + <tbody>
  47 + <tr>
  48 + <td>
  49 + <span class="date">dd/mm/aaaa</span>
  50 + <span class="separator">-</span>
  51 + <span class="time">HH:mm</span>
  52 + <span class="separator">-</span>
  53 + <span class="description">Mais médicos, Segurança Nacional, SAMU</span>
  54 + <button type="button" class="btn color-theme-common-bg" ng-click="eventListCtrl.subscribe('EVENT_ID')">
  55 + Inscreva-se
  56 + <span class="sr-only">no bate-papo com (ministro) no dia (date) as (hh:mm) horas</span>
  57 + </button>
  58 + <span class="subscribers">123 inscritos</span>
  59 + </td>
  60 + </tr>
  61 + <tr>
  62 + <td>
  63 + <span class="date">dd/mm/aaaa</span>
  64 + <span class="separator">-</span>
  65 + <span class="time">HH:mm</span>
  66 + <span class="separator">-</span>
  67 + <span class="description">Mais médicos, Segurança Nacional, SAMU</span>
  68 + <button type="button" class="btn color-theme-common-bg">Inscreva-se</button>
  69 + <span class="subscribers">123 inscritos</span>
  70 + </td>
  71 + </tr>
  72 + <tr>
  73 + <td>
  74 + <span class="date">dd/mm/aaaa</span>
  75 + <span class="separator">-</span>
  76 + <span class="time">HH:mm</span>
  77 + <span class="separator">-</span>
  78 + <span class="description">Mais médicos, Segurança Nacional, SAMU</span>
  79 + <button type="button" class="btn color-theme-common-bg">Inscreva-se</button>
  80 + <span class="subscribers">123 inscritos</span>
  81 + </td>
  82 + </tr>
  83 + <tr>
  84 + <td>
  85 + <span class="date">dd/mm/aaaa</span>
  86 + <span class="separator">-</span>
  87 + <span class="time">HH:mm</span>
  88 + <span class="separator">-</span>
  89 + <span class="description">Mais médicos, Segurança Nacional, SAMU</span>
  90 + <button type="button" class="btn color-theme-common-bg">Inscreva-se</button>
  91 + <span class="subscribers">123 inscritos</span>
  92 + </td>
  93 + </tr>
  94 + <tr>
  95 + <td>
  96 + <span class="date">dd/mm/aaaa</span>
  97 + <span class="separator">-</span>
  98 + <span class="time">HH:mm</span>
  99 + <span class="separator">-</span>
  100 + <span class="description">Mais médicos, Segurança Nacional, SAMU</span>
  101 + <button type="button" class="btn color-theme-common-bg">Inscreva-se</button>
  102 + <span class="subscribers">123 inscritos</span>
  103 + </td>
  104 + </tr>
  105 + <tr>
  106 + <td>
  107 + <span class="date">dd/mm/aaaa</span>
  108 + <span class="separator">-</span>
  109 + <span class="time">HH:mm</span>
  110 + <span class="separator">-</span>
  111 + <span class="description">Mais médicos, Segurança Nacional, SAMU</span>
  112 + <button type="button" class="btn color-theme-common-bg">Inscreva-se</button>
  113 + <span class="subscribers">123 inscritos</span>
  114 + </td>
  115 + </tr>
  116 + </tbody>
  117 + <!-- <tfooter></tfooter> -->
  118 + </table>
  119 + </div>
  120 + </div>
27 </div> 121 </div>
28 </div> 122 </div>
29 - <div class="event-list--table-wrapper">  
30 - <div class="table-responsive">  
31 - <table class="table event-list--table">  
32 - <!-- <thead></thead> -->  
33 - <tbody>  
34 - <tr>  
35 - <td>  
36 - <span class="date">dd/mm/aaaa</span>  
37 - <span class="separator">-</span>  
38 - <span class="time">HH:mm</span>  
39 - <span class="separator">-</span>  
40 - <span class="description">Mais médicos, Segurança Nacional, SAMU</span>  
41 - <button type="button" class="btn" ng-click="eventListCtrl.subscribe('EVENT_ID')">  
42 - Inscreva-se  
43 - <span class="sr-only">no bate-papo com (ministro) no dia (date) as (hh:mm) horas</span>  
44 - </button>  
45 - <span class="subscribers">123 inscritos</span>  
46 - </td>  
47 - </tr>  
48 - <tr>  
49 - <td>  
50 - <span class="date">dd/mm/aaaa</span>  
51 - <span class="separator">-</span>  
52 - <span class="time">HH:mm</span>  
53 - <span class="separator">-</span>  
54 - <span class="description">Mais médicos, Segurança Nacional, SAMU</span>  
55 - <button type="button" class="btn">Inscreva-se</button>  
56 - <span class="subscribers">123 inscritos</span>  
57 - </td>  
58 - </tr>  
59 - <tr>  
60 - <td>  
61 - <span class="date">dd/mm/aaaa</span>  
62 - <span class="separator">-</span>  
63 - <span class="time">HH:mm</span>  
64 - <span class="separator">-</span>  
65 - <span class="description">Mais médicos, Segurança Nacional, SAMU</span>  
66 - <button type="button" class="btn">Inscreva-se</button>  
67 - <span class="subscribers">123 inscritos</span>  
68 - </td>  
69 - </tr>  
70 - <tr>  
71 - <td>  
72 - <span class="date">dd/mm/aaaa</span>  
73 - <span class="separator">-</span>  
74 - <span class="time">HH:mm</span>  
75 - <span class="separator">-</span>  
76 - <span class="description">Mais médicos, Segurança Nacional, SAMU</span>  
77 - <button type="button" class="btn">Inscreva-se</button>  
78 - <span class="subscribers">123 inscritos</span>  
79 - </td>  
80 - </tr>  
81 - <tr>  
82 - <td>  
83 - <span class="date">dd/mm/aaaa</span>  
84 - <span class="separator">-</span>  
85 - <span class="time">HH:mm</span>  
86 - <span class="separator">-</span>  
87 - <span class="description">Mais médicos, Segurança Nacional, SAMU</span>  
88 - <button type="button" class="btn">Inscreva-se</button>  
89 - <span class="subscribers">123 inscritos</span>  
90 - </td>  
91 - </tr>  
92 - <tr>  
93 - <td>  
94 - <span class="date">dd/mm/aaaa</span>  
95 - <span class="separator">-</span>  
96 - <span class="time">HH:mm</span>  
97 - <span class="separator">-</span>  
98 - <span class="description">Mais médicos, Segurança Nacional, SAMU</span>  
99 - <button type="button" class="btn">Inscreva-se</button>  
100 - <span class="subscribers">123 inscritos</span>  
101 - </td>  
102 - </tr>  
103 - </tbody>  
104 - <!-- <tfooter></tfooter> -->  
105 - </table>  
106 - </div>  
107 - </div>  
108 - </div> 123 + </section>
109 </div> 124 </div>
src/app/components/event-list/event-list.scss
1 .event-list { 1 .event-list {
2 position: relative; 2 position: relative;
3 - background-color: #eeeeee;  
4 3
5 .contraste & { 4 .contraste & {
6 background-color: #262626; 5 background-color: #262626;
7 } 6 }
8 7
  8 + .section-table {
  9 + background-color: #e1e1e1;
  10 + }
  11 +
9 .event-list--panel { 12 .event-list--panel {
10 height: 310px; 13 height: 310px;
11 - border: 1px solid #333333;  
12 padding: 20px; 14 padding: 20px;
13 margin: 20px 0; 15 margin: 20px 0;
14 line-height: 20px; 16 line-height: 20px;
@@ -19,25 +21,25 @@ @@ -19,25 +21,25 @@
19 line-height: 0px; 21 line-height: 0px;
20 } 22 }
21 23
22 - .event-list--header {  
23 - border-bottom: 1px solid #333333;  
24 - } 24 + // .event-list--header {
  25 + // border-bottom: 1px solid #333333;
  26 + // }
25 27
26 - .event-list--icon {  
27 - font-size: 25px;  
28 - display: inline-block;  
29 - } 28 + // .event-list--icon {
  29 + // font-size: 25px;
  30 + // display: inline-block;
  31 + // }
30 32
31 - .event-list--title {  
32 - margin: 0 10px;  
33 - display: inline-block;  
34 - } 33 + // .event-list--title {
  34 + // margin: 0 10px;
  35 + // display: inline-block;
  36 + // }
35 37
36 - .event-list--minimize {  
37 - display: inline-block;  
38 - float: right;  
39 - width: 100px;  
40 - } 38 + // .event-list--minimize {
  39 + // display: inline-block;
  40 + // float: right;
  41 + // width: 100px;
  42 + // }
41 } 43 }
42 44
43 .event-tab--trigger { 45 .event-tab--trigger {
@@ -68,14 +70,51 @@ @@ -68,14 +70,51 @@
68 } 70 }
69 } 71 }
70 72
  73 + .event-bar--trigger {
  74 + color: #fff;
  75 +
  76 + h1 {
  77 + margin-bottom: 20px;
  78 + }
  79 +
  80 + .icon-circle {
  81 + font-size: 28px;
  82 + border-radius: 100%;
  83 + padding: 8px 8px 8px 10px;
  84 + background-color: #fff;
  85 + }
  86 +
  87 + &-toggle {
  88 + .glyphicon {
  89 + position: relative;
  90 + top: 5px;
  91 + }
  92 + }
  93 + }
  94 +
71 .table-responsive { 95 .table-responsive {
72 - height: 250px; 96 + width: 100%;
  97 + height: 240px;
73 overflow-y: scroll; 98 overflow-y: scroll;
  99 +
  100 + .btn {
  101 + color: #e1e1e1;
  102 + text-transform: uppercase;
  103 + font-weight: bold;
  104 + }
  105 +
  106 + tr > td {
  107 + border-top: 1px solid #ccc;
  108 + }
  109 + tr:last-child > td {
  110 + border-bottom: 1px solid #ccc;
  111 + }
74 } 112 }
75 113
76 .event-tab--icon { 114 .event-tab--icon {
77 font-size: 25px; 115 font-size: 25px;
78 } 116 }
  117 +
79 .event-tab--title { 118 .event-tab--title {
80 font-weight: bold; 119 font-weight: bold;
81 } 120 }
src/app/components/navbar/navbar.html
1 -<nav id="navigation" class="header-navbar navbar navbar-static-top" role="navigation">  
2 - <div class="navbar-header">  
3 - <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse" aria-expanded="false">  
4 - <span class="sr-only">Alternar menu de navegação</span>  
5 - <span class="icon-bar" aria-hidden="true"></span>  
6 - <span class="icon-bar" aria-hidden="true"></span>  
7 - <span class="icon-bar" aria-hidden="true"></span>  
8 - </button>  
9 - <a class="navbar-brand" ui-sref="inicio">  
10 - <img src="/assets/images/logo.png" alt="Dialoga Brasil | O país fica melhor quando você participa" />  
11 - <!-- <span class="glyphicon glyphicon-home"></span> Início -->  
12 - </a>  
13 - </div> 1 +<div class="app-navbar">
  2 + <nav id="navigation" class="header-navbar navbar navbar-static-top" role="navigation">
  3 + <div class="navbar-header">
  4 + <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse" aria-expanded="false">
  5 + <span class="sr-only">Alternar menu de navegação</span>
  6 + <span class="icon-bar" aria-hidden="true"></span>
  7 + <span class="icon-bar" aria-hidden="true"></span>
  8 + <span class="icon-bar" aria-hidden="true"></span>
  9 + </button>
  10 + <a class="navbar-brand" ui-sref="inicio">
  11 + <img src="/assets/images/logo.png" alt="Dialoga Brasil | O país fica melhor quando você participa" />
  12 + <!-- <span class="glyphicon glyphicon-home"></span> Início -->
  13 + </a>
  14 + </div>
14 15
15 - <div id="navbar-collapse" class="collapse navbar-collapse">  
16 - <ul class="nav navbar-nav">  
17 - <li><a ui-sref="sobre">Sobre</a></li>  
18 - <li><a ui-sref="programas">Programas</a></li>  
19 - <li><a ui-sref="propostas">Propostas</a></li>  
20 - <!-- <li><a ui-sref="ranking">Ranking</a></li> -->  
21 - <li><a ui-sref="duvidas">Dúvidas</a></li>  
22 - <!-- <li><a ui-sref="respostas">Respostas</a></li> -->  
23 - </ul>  
24 - </div>  
25 -</nav> 16 + <div id="navbar-collapse" class="collapse navbar-collapse">
  17 + <ul class="nav navbar-nav navbar-right">
  18 + <li ui-sref-active="active"><a ui-sref="sobre">Sobre</a></li>
  19 + <li ui-sref-active="active"><a ui-sref="programas">Programas</a></li>
  20 + <li ui-sref-active="active"><a ui-sref="propostas">Propostas</a></li>
  21 + <li ui-sref-active="active"><a ui-sref="ranking">Ranking</a></li>
  22 + <li ui-sref-active="active"><a ui-sref="duvidas">Dúvidas</a></li>
  23 + <!-- <li ui-sref-active="active"><a ui-sref="respostas">Respostas</a></li> -->
  24 + <li role="separator" class="divider"><span>|</span></li>
  25 + <li class="dropdown">
  26 + <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Compartilhar <span class="icon-circle"><span class="glyphicon glyphicon-share-alt"></span></span></a>
  27 + <ul class="dropdown-menu">
  28 + <li>
  29 + <a social-facebook custom-url="http://dialoga.gov.br" title="Compartilhar no Facebook">
  30 + <span class="icon icon-social-facebook"></span>
  31 + <span class="sr-only">Compartilhar no Facebook</span>
  32 + </a>
  33 + </li>
  34 + <li>
  35 + <a social-twitter custom-url="http://dialoga.gov.br" status="This status is #{{ vm.status }}" title="Compartilhar no Twitter">
  36 + <span class="icon icon-social-twitter"></span>
  37 + <span class="sr-only">Compartilhar no Twitter</span>
  38 + </a>
  39 + </li>
  40 + <li>
  41 + <a social-gplus custom-url="http://dialoga.gov.br" title="Compartilhar no Google Plus">
  42 + <span class="icon icon-social-google-plus"></span>
  43 + <span class="sr-only">Compartilhar no Google Plus</span>
  44 + </a>
  45 + </li>
  46 + <!-- <li>
  47 + <a href="whatsapp://send?text=http%3A%2F%2Fdialoga.gov.br" target="_blank" title="Compartilhar no WhatsApp">
  48 + <span class="icon icon-social-whatsapp"></span>
  49 + <span class="sr-only">Compartilhar no WhatsApp</span>
  50 + </a>
  51 + </li> -->
  52 + <li>
  53 + <a href="mailto:contato@dialoga.gov.br?subject=Conheça o Dialoga Brasil" title="Enviar por email">
  54 + <span class="icon icon-social-whatsapp"></span>
  55 + <span class="sr-only">Enviar por email</span>
  56 + </a>
  57 + </li>
  58 + </ul>
  59 + </li>
  60 + </ul>
  61 + </div>
  62 + </nav>
  63 +</div>
src/app/components/navbar/navbar.scss
1 -.header-navbar { 1 +.app-navbar {
  2 +
  3 + border-bottom: 2px solid #f1f1f1;
  4 + margin-bottom: 20px;
  5 +
  6 + .navbar {
  7 + margin-bottom: 0;
  8 + border: none;
  9 + }
2 10
3 .navbar-brand { 11 .navbar-brand {
4 height: auto; 12 height: auto;
@@ -14,19 +22,62 @@ @@ -14,19 +22,62 @@
14 } 22 }
15 } 23 }
16 24
17 - .navbar-nav a {  
18 - padding-top: 30px;  
19 - padding-bottom: 30px;  
20 - text-transform: uppercase;  
21 - color: #03316f; 25 + .navbar-nav .divider span {
  26 + padding: 0 0 10px 0;
  27 + margin: 53px 10px 0 10px;
  28 + display: block;
  29 +
  30 + @media screen and (max-width: 768px) {
  31 + display: none;
  32 + }
  33 + }
  34 +
  35 + .navbar-nav > li {
22 36
23 - -webkit-transition: all 0.2s ease-in-out;  
24 - -moz-transition: all 0.2s ease-in-out;  
25 - -o-transition: all 0.2s ease-in-out;  
26 - transition: all 0.2s ease-in-out; 37 + & > a {
  38 + padding: 0 0 10px 0;
  39 + margin: 55px 10px 0 10px;
  40 + text-transform: uppercase;
  41 + color: #616161;
  42 + font-weight: bold;
27 43
28 - .contraste & {  
29 - color: #fff; 44 + &:hover,
  45 + &:focus {
  46 + background: none;
  47 + }
  48 +
  49 + .contraste & {
  50 + color: #fff;
  51 + }
  52 + }
  53 +
  54 + &.active > a {
  55 + border-bottom: 3px solid #77BB34;
  56 +
  57 + @media screen and (max-width: 768px) {
  58 + border: none;
  59 + background-color: #eee;
  60 + padding: 10px 0 10px 0px;
  61 + }
  62 + }
  63 +
  64 + .dropdown-menu {
  65 + min-width: 190px;
  66 +
  67 + li {
  68 + float: left;
  69 + padding: 0;
  70 + margin: 0;
  71 + width: 45px;
  72 +
  73 + & > a {
  74 + padding: 0;
  75 + }
  76 +
  77 + &:first-child {
  78 + margin-left: 5px;
  79 + }
  80 + }
30 } 81 }
31 } 82 }
32 83
@@ -37,8 +88,11 @@ @@ -37,8 +88,11 @@
37 .contraste & { 88 .contraste & {
38 .nav > li > a:hover, 89 .nav > li > a:hover,
39 .nav > li > a:focus { 90 .nav > li > a:focus {
40 - color: #000; 91 + color: #fff;
41 } 92 }
42 93
  94 + .active a {
  95 + border-bottom-color: #fff;
  96 + }
43 } 97 }
44 } 98 }
src/app/components/programas/programas.directive.js
@@ -1,316 +0,0 @@ @@ -1,316 +0,0 @@
1 -(function() {  
2 - 'use strict';  
3 -  
4 - angular  
5 - .module('dialoga')  
6 - .directive('programaList', programaList);  
7 -  
8 - /** @ngInject */  
9 - function programaList() {  
10 -  
11 - /** @ngInject */  
12 - function ProgramaListController($scope, $element, $location, $filter, $log) {  
13 - $log.debug('ProgramaListController');  
14 -  
15 - // alias  
16 - var vm = this;  
17 -  
18 - // dependencies  
19 - vm.$scope = $scope;  
20 - vm.$element = $element;  
21 - vm.$location = $location;  
22 - vm.$filter = $filter;  
23 - vm.$log = $log;  
24 - vm.defaultLimit = 6;  
25 -  
26 - // initialization  
27 - vm.init();  
28 - }  
29 -  
30 - ProgramaListController.prototype.init = function() {  
31 - var vm = this;  
32 -  
33 - if (!vm.article) {  
34 - vm.$log.warn('no article to display. Tip: use a ng-if before use this directive');  
35 - return;  
36 - }  
37 -  
38 - vm.categories = vm.article.categories;  
39 - vm.programs = vm.article.children;  
40 - vm.orderCriteries = [  
41 - { label: 'Título', name: 'titulo' },  
42 - { label: 'Tema', name: 'tema' },  
43 - { label: 'Aleatório', name: 'aleatorio' }  
44 - ];  
45 -  
46 - vm.filtredProgramList = vm.getFiltredPrograms();  
47 - vm.search = vm.$location.search();  
48 -  
49 - // Add initial values for the filter  
50 - vm.query = (vm.search && vm.search.filtro) ? vm.search.filtro : null;  
51 - vm.limitTo = (vm.search && vm.search.limite) ? parseInt(vm.search.limite, 10) : vm.defaultLimit;  
52 - vm.categoryFilter = (vm.search && vm.search.tema) ? vm.getCategoryBySlug(vm.search.tema) : null;  
53 - vm.orderCriteria = (vm.search && vm.search.ordem) ? { name: vm.search.ordem } : null;  
54 - vm.reverse = (vm.search && vm.search.reverso) ? true : false;  
55 -  
56 - if (!angular.equals({}, vm.search)) {  
57 - var $el = vm.$element;  
58 - angular.element('body').animate({scrollTop: $el.offset().top}, 'slow');  
59 - }  
60 -  
61 - // update window location params  
62 - vm.$scope.$watch('vm.query', function(newValue/*, oldValue*/) {  
63 - vm.search.filtro = newValue ? newValue : null;  
64 - vm.$location.search('filtro', vm.search.filtro);  
65 - if(vm.search.filtro){  
66 - vm.limitTo = vm.programs.length;  
67 - }else{  
68 - vm.limitTo = vm.defaultLimit;  
69 - }  
70 - vm.filtredProgramList = vm.getFiltredPrograms();  
71 - });  
72 -  
73 - vm.$scope.$watch('vm.limitTo', function(newValue/*, oldValue*/) {  
74 - vm.search.limite = (newValue && newValue !== vm.defaultLimit) ? newValue : null;  
75 - vm.$location.search('limite', vm.search.limite);  
76 - vm.filtredProgramList = vm.getFiltredPrograms();  
77 - });  
78 -  
79 - vm.$scope.$watch('vm.categoryFilter', function(newValue/*, oldValue*/) {  
80 - vm.search.tema = newValue ? newValue.slug : null;  
81 - vm.$location.search('tema', vm.search.tema);  
82 - if(vm.search.tema){  
83 - vm.limitTo = vm.programs.length;  
84 - }  
85 - vm.filtredProgramList = vm.getFiltredPrograms();  
86 - });  
87 -  
88 - vm.$scope.$watch('vm.orderCriteria', function(newValue/*, oldValue*/) {  
89 - vm.search.ordem = (newValue && newValue.name) ? newValue.name : null;  
90 - vm.$location.search('ordem', vm.search.ordem);  
91 - vm.filtredProgramList = vm.getFiltredPrograms();  
92 - });  
93 -  
94 - vm.$scope.$watch('vm.reverse', function(newValue/*, oldValue*/) {  
95 - vm.search.reverso = newValue ? newValue : null;  
96 - vm.$location.search('reverso', vm.search.reverso);  
97 - vm.filtredProgramList = vm.getFiltredPrograms();  
98 - });  
99 -  
100 - };  
101 -  
102 - ProgramaListController.prototype.resetFilterValues = function() {  
103 - var vm = this;  
104 -  
105 - vm.query = null;  
106 - vm.limitTo = vm.defaultLimit;  
107 - vm.categoryFilter = null;  
108 - vm.orderCriteria = null;  
109 - };  
110 -  
111 - ProgramaListController.prototype.getIconClasses = function(category) {  
112 - var vm = this;  
113 -  
114 - vm.$log.debug('[TODO] getIconClasses of category:', category);  
115 - return 'glyphicon glyphicon-exclamation-sign';  
116 - };  
117 -  
118 - ProgramaListController.prototype.getCategoryBySlug = function(categorySlug) {  
119 - var vm = this;  
120 - var result = null;  
121 -  
122 - angular.forEach(vm.categories, function(value/*, key*/) {  
123 - if (value.slug === categorySlug) {  
124 - result = value;  
125 - }  
126 - });  
127 -  
128 - return result;  
129 - };  
130 -  
131 - ProgramaListController.prototype.filterByCategory = function(category, $event) {  
132 - var vm = this;  
133 -  
134 - $event.stopPropagation();  
135 -  
136 - if (category !== vm.categoryFilter) {  
137 -  
138 - // selected new filter  
139 - vm.categoryFilter = category;  
140 - } else {  
141 - vm.categoryFilter = null;  
142 - }  
143 - };  
144 -  
145 - ProgramaListController.prototype.showAll = function($event) {  
146 - var vm = this;  
147 -  
148 - $event.stopPropagation();  
149 -  
150 - vm.resetFilterValues();  
151 - vm.limitTo = vm.programs.length;  
152 - };  
153 -  
154 - ProgramaListController.prototype.getFiltredPrograms = function() {  
155 - var vm = this;  
156 -  
157 - var input = vm.programs;  
158 - var output = input;  
159 - var query = vm.query;  
160 - var categoryFilter = vm.categoryFilter;  
161 - var orderCriteria = vm.orderCriteria ? vm.orderCriteria : { name : 'aleatorio'};  
162 - var filter = vm.$filter('filter');  
163 - var orderBy = vm.$filter('orderBy');  
164 - var limitTo = vm.$filter('limitTo');  
165 - var limit = vm.limitTo ? vm.limitTo : 4;  
166 -  
167 - if (categoryFilter) {  
168 - output = _filterByCategory(output, categoryFilter);  
169 - }  
170 -  
171 - if (query) {  
172 - output = filter(output, query, false);  
173 - }  
174 -  
175 - switch (orderCriteria.name) {  
176 - case 'titulo':  
177 - output = orderBy(output, 'title', vm.reverse);  
178 - break;  
179 - case 'tema':  
180 - output = orderBy(output, 'categories[0].name', vm.reverse);  
181 - break;  
182 - case 'more_participants':  
183 - vm.$log.info('Criteria not handled yet: ', orderCriteria);  
184 - break;  
185 - case 'aleatorio':  
186 - // shuffling  
187 - // if (!vm._isShuffled){  
188 - output = vm.filterShuffle(output);  
189 - // vm._isShuffled = true;  
190 - // }  
191 -  
192 - if (vm.reverse) {  
193 - output = output.slice().reverse();  
194 - }  
195 -  
196 - break;  
197 - default:  
198 - vm.$log.warn('Criteria not matched: ', orderCriteria);  
199 - break;  
200 - }  
201 -  
202 - output = limitTo(output, limit);  
203 -  
204 - return output;  
205 - };  
206 -  
207 - ProgramaListController.prototype.filterShuffle = function(input) {  
208 - var result = [];  
209 - var resultByCategory = {};  
210 -  
211 - // divide by categories  
212 - for (var i = 0; i < input.length; i++) {  
213 - var program = input[i];  
214 - var categorySlug = program.categories[0].slug;  
215 -  
216 - if (!resultByCategory[categorySlug]) {  
217 - resultByCategory[categorySlug] = [];  
218 - }  
219 -  
220 - resultByCategory[categorySlug].push(program);  
221 - }  
222 -  
223 - // shuffle each array  
224 - var prop = null;  
225 - var categoryWithPrograms = null;  
226 - for (prop in resultByCategory) {  
227 - if (resultByCategory.hasOwnProperty(prop)) {  
228 - categoryWithPrograms = resultByCategory[prop];  
229 - resultByCategory[prop] = shuffle(categoryWithPrograms);  
230 - }  
231 - }  
232 -  
233 - // Concat all into result array  
234 - // > while has program at Lists on resultByCategory  
235 - var hasProgram = true;  
236 - while (hasProgram) {  
237 -  
238 - var foundProgram = false;  
239 - // each categoryList with array of program  
240 - prop = null;  
241 - categoryWithPrograms = null;  
242 - for (prop in resultByCategory) {  
243 -  
244 - if (resultByCategory.hasOwnProperty(prop)) {  
245 - categoryWithPrograms = resultByCategory[prop];  
246 -  
247 - if (categoryWithPrograms.length > 0) {  
248 - var pivotProgram = categoryWithPrograms.pop();  
249 - result.push(pivotProgram);  
250 - foundProgram = true;  
251 - }  
252 - }  
253 - }  
254 -  
255 - if (!foundProgram) {  
256 - hasProgram = false;  
257 - }  
258 - }  
259 -  
260 - return result;  
261 - };  
262 -  
263 - var directive = {  
264 - restrict: 'E',  
265 - templateUrl: 'app/components/programas/programas.html',  
266 - scope: {  
267 - article: '='  
268 - },  
269 - controller: ProgramaListController,  
270 - controllerAs: 'vm',  
271 - bindToController: true  
272 - };  
273 -  
274 - return directive;  
275 - }  
276 -  
277 - function _filterByCategory (input, category) {  
278 - input = input || [];  
279 -  
280 - if (!category) {  
281 - // no filter  
282 - return input;  
283 - }  
284 -  
285 - var out = [];  
286 - for (var i = 0; i < input.length; i++) {  
287 - var program = input[i];  
288 - if (program.categories[0].slug === category.slug) {  
289 - out.push(program);  
290 - }  
291 - }  
292 -  
293 - return out;  
294 - }  
295 -  
296 - // -> Fisher–Yates shuffle algorithm  
297 - function shuffle (array) {  
298 - var currentIndex = array.length, temporaryValue, randomIndex ;  
299 -  
300 - // While there remain elements to shuffle...  
301 - while (0 !== currentIndex) {  
302 -  
303 - // Pick a remaining element...  
304 - randomIndex = Math.floor(Math.random() * currentIndex);  
305 - currentIndex -= 1;  
306 -  
307 - // And swap it with the current element.  
308 - temporaryValue = array[currentIndex];  
309 - array[currentIndex] = array[randomIndex];  
310 - array[randomIndex] = temporaryValue;  
311 - }  
312 -  
313 - return array;  
314 - }  
315 -  
316 -})();  
src/app/components/programas/programas.directive.spec.js
@@ -1,32 +0,0 @@ @@ -1,32 +0,0 @@
1 -(function() {  
2 - 'use strict';  
3 -  
4 - describe('program directive', function() {  
5 - var compile, scope, directiveElem;  
6 -  
7 - beforeEach(function(){  
8 - module('dialoga');  
9 -  
10 - inject(function($compile, $rootScope){  
11 - compile = $compile;  
12 - scope = $rootScope.$new();  
13 - // mock article  
14 - scope.article = {};  
15 - });  
16 -  
17 - directiveElem = getCompiledElement();  
18 - });  
19 -  
20 - function getCompiledElement(){  
21 - var element = compile(angular.element('<programa-list></programa-list>'))(scope);  
22 - var compiledElement = compile(element)(scope);  
23 - scope.$digest();  
24 - return compiledElement;  
25 - }  
26 -  
27 - it('ensure exist only one id "lista-de-programas"', function() {});  
28 -  
29 - it('should show default programs, one each category', function() {});  
30 -  
31 - });  
32 -})();  
src/app/components/proposal-carousel/proposal-carousel.directive.js 0 → 100644
@@ -0,0 +1,71 @@ @@ -0,0 +1,71 @@
  1 +(function() {
  2 + 'use strict';
  3 +
  4 + angular
  5 + .module('dialoga')
  6 + .directive('proposalCarousel', proposalCarousel);
  7 +
  8 + /** @ngInject */
  9 + function proposalCarousel() {
  10 +
  11 + /** @ngInject */
  12 + function ProposalCarouselController($scope, $element, $timeout, $log) {
  13 + $log.debug('ProposalCarouselController');
  14 +
  15 + var vm = this;
  16 + vm.$scope = $scope;
  17 + vm.$element = $element;
  18 + vm.$timeout = $timeout;
  19 + vm.$log = $log;
  20 +
  21 + vm.init();
  22 + }
  23 +
  24 + ProposalCarouselController.prototype.init = function () {
  25 + // initial values
  26 + var vm = this;
  27 +
  28 + if(!vm.proposals){
  29 + throw { name: 'NotDefined', message: 'The attribute "proposals" is undefined.'};
  30 + }
  31 +
  32 + vm.activeIndex = 0;
  33 + vm.loading = false;
  34 + vm.proposalsLength = vm.proposals.length;
  35 + };
  36 +
  37 + ProposalCarouselController.prototype.swipeLeft = function () {
  38 + var vm = this;
  39 +
  40 + vm.activeIndex = (vm.activeIndex < vm.proposalsLength - 1) ? ++vm.activeIndex : 0;
  41 + };
  42 +
  43 + ProposalCarouselController.prototype.swipeRight = function () {
  44 + var vm = this;
  45 +
  46 + vm.activeIndex = (vm.activeIndex > 0) ? --vm.activeIndex : vm.proposalsLength - 1;
  47 + };
  48 +
  49 + ProposalCarouselController.prototype.showProposals = function () {
  50 + var vm = this;
  51 +
  52 + // notify parents - handled by parents
  53 + vm.$scope.$emit('proposal-carousel:toProposals');
  54 + };
  55 +
  56 + var directive = {
  57 + restrict: 'E',
  58 + templateUrl: 'app/components/proposal-carousel/proposal-carousel.html',
  59 + scope: {
  60 + proposals: '='
  61 + },
  62 + controller: ProposalCarouselController,
  63 + controllerAs: 'vm',
  64 + bindToController: true
  65 + };
  66 +
  67 +
  68 + return directive;
  69 + }
  70 +
  71 +})();
src/app/components/proposal-carousel/proposal-carousel.html 0 → 100644
@@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
  1 +<div class="proposal-carousel">
  2 + <div ng-if="vm.proposals">
  3 + <div class="proposal-carousel-top color-theme-bg">
  4 + <div class="proposal-carousel-position" ng-repeat="proposal in vm.proposals">
  5 + <span ng-show="vm.activeIndex === $index">{{::($index+1)}}º</span>
  6 + <span ng-show="vm.activeIndex === $index">Lugar</span>
  7 + </div>
  8 + <div class="proposal-carousel-top-triggers" ng-if="vm.proposals">
  9 + <ul class="list-inline">
  10 + <li class="item-dot" ng-repeat="proposal in vm.proposals">
  11 + <button type="button" ng-class="{'active': vm.activeIndex === $index}" ng-click="vm.switchProposal($index)" title="Apersentar proposta na posição {{$index}}"></button>
  12 + </li>
  13 + </ul>
  14 + </div>
  15 + </div>
  16 + <div class="proposal-carousel-middle" ng-swipe-left="vm.swipeLeft()" ng-swipe-right="vm.swipeRight()">
  17 + <div ng-repeat="proposal in vm.proposals" class="animation-swipe">
  18 + <div class="content">
  19 + <div ng-show="vm.activeIndex === $index">{{::proposal.abstract}}</div>
  20 + </div>
  21 + <div class="proposal-carousel-middle-watermark" ng-show="vm.activeIndex === $index">
  22 + <span>{{::($index+1)}}º</span>
  23 + </div>
  24 + </div>
  25 + </div>
  26 + <div class="proposal-carousel-bottom color-theme-common-bg" ng-click="vm.showProposals()">
  27 + <div>Veja as propostas mais vortadas</div>
  28 + <div class="proposal-carousel-bottom-icon">
  29 + <span class="glyphicon glyphicon-chevron-down pull-right color-theme-common-fg"></span>
  30 + </div>
  31 + </div>
  32 + </div>
  33 +</div>
src/app/components/proposal-carousel/proposal-carousel.scss 0 → 100644
@@ -0,0 +1,86 @@ @@ -0,0 +1,86 @@
  1 +.proposal-carousel {
  2 + background-color: #f1f1f1;
  3 + border-radius: 5px;
  4 + overflow: hidden;
  5 +
  6 + &-top {
  7 + position: relative;
  8 + color: #fff;
  9 + font-weight: bold;
  10 + font-size: 25px;
  11 + padding: 20px 15px;
  12 +
  13 + &-triggers {
  14 + position: absolute;
  15 + right: 15px;
  16 + top: 20px;
  17 +
  18 + button {
  19 + border: 1px solid #fff;
  20 + border-radius: 100%;
  21 + width: 15px;
  22 + height: 15px;
  23 + margin-right: 5px;
  24 + background-color: transparent;
  25 +
  26 + cursor: pointer;
  27 +
  28 + &.active {
  29 + background-color: #fff;
  30 + }
  31 + }
  32 + }
  33 + }
  34 +
  35 + &-middle {
  36 + position: relative;
  37 + padding: 25px 30px;
  38 + min-height: 200px;
  39 + // cursor: pointer;
  40 + -webkit-user-select: none;
  41 + -khtml-user-select: none;
  42 + -moz-user-select: none;
  43 + -ms-user-select: none;
  44 + user-select: none;
  45 +
  46 + .content {
  47 + position: relative;
  48 + z-index: 2;
  49 + }
  50 +
  51 + &-watermark {
  52 + position: absolute;
  53 + bottom: 1px;
  54 + left: -5px;
  55 + color: #ddd;
  56 + font-size: 150px;
  57 + font-weight: bold;
  58 + line-height: 116px;
  59 + z-index: 1;
  60 +
  61 + }
  62 + }
  63 +
  64 + &-bottom {
  65 + position: relative;
  66 + color: #fff;
  67 + padding: 10px;
  68 + font-weight: bold;
  69 + cursor: pointer;
  70 + z-index: 10;
  71 +
  72 + &-icon {
  73 + position: absolute;
  74 + top: 10px;
  75 + right: 15px;
  76 +
  77 + .glyphicon {
  78 + position: relative;
  79 + top: -2px;
  80 + background-color: #fff;
  81 + padding: 6px 5px 5px 6px;
  82 + border-radius: 100%;
  83 + }
  84 + }
  85 + }
  86 +}
src/app/components/proposal-list/proposal-list.directive.js 0 → 100644
@@ -0,0 +1,81 @@ @@ -0,0 +1,81 @@
  1 +(function() {
  2 + 'use strict';
  3 +
  4 + angular
  5 + .module('dialoga')
  6 + .directive('proposalList', proposalList);
  7 +
  8 + /** @ngInject */
  9 + function proposalList() {
  10 +
  11 + /** @ngInject */
  12 + function ProposalListController(ArticleService, $scope, $element, $timeout, $log) {
  13 + $log.debug('ProposalListController');
  14 +
  15 + var vm = this;
  16 + vm.ArticleService = ArticleService;
  17 + vm.$scope = $scope;
  18 + vm.$element = $element;
  19 + vm.$timeout = $timeout;
  20 + vm.$log = $log;
  21 +
  22 + vm.init();
  23 +
  24 + vm.loadData();
  25 + }
  26 +
  27 + ProposalListController.prototype.init = function () {
  28 + // initial values
  29 + var vm = this;
  30 +
  31 + if(!vm.proposals){
  32 + throw { name: 'NotDefined', message: 'The attribute "proposals" is undefined.'};
  33 + }
  34 +
  35 + if(!vm.per_page){
  36 + vm.per_page = 5;
  37 + }
  38 +
  39 + vm.proposalsLength = vm.proposals.length;
  40 + };
  41 +
  42 + ProposalListController.prototype.loadData = function () {
  43 + // async values
  44 + var vm = this;
  45 +
  46 + // requeue to wait until DOM be created
  47 + vm.$timeout(function(){
  48 + attachPopover.call(vm);
  49 + }, 100);
  50 + };
  51 +
  52 + function attachPopover(){
  53 + var vm = this;
  54 +
  55 + vm.popover = angular.element(vm.$element.find('.btn-question'));
  56 + vm.popover.popover({
  57 + html: true,
  58 + placement: 'bottom',
  59 + animation: true,
  60 + title: 'Regra de posição das propostas',
  61 + content: '<p>É calculada pelo saldo de interações das propostas (curtidas - não curtidas) dividido pela diferença de exibições entre elas.</p><p>O objetivo dessa correção é compensar o saldo de interações e a diferença de exibições das propostas que não tiveram muitas oportunidades de visualização ou das propostas que tiveram mais oportunidades de visualização que a média.</p><p>Com essa correção, é possível comparar propostas que entraram em diferentes momentos, durante todo o período da consulta.</p>'
  62 + });
  63 + }
  64 +
  65 + var directive = {
  66 + restrict: 'E',
  67 + templateUrl: 'app/components/proposal-list/proposal-list.html',
  68 + scope: {
  69 + proposals: '=',
  70 + per_page: '='
  71 + },
  72 + controller: ProposalListController,
  73 + controllerAs: 'vm',
  74 + bindToController: true
  75 + };
  76 +
  77 +
  78 + return directive;
  79 + }
  80 +
  81 +})();
src/app/components/proposal-list/proposal-list.html 0 → 100644
@@ -0,0 +1,45 @@ @@ -0,0 +1,45 @@
  1 +<div class="proposal-list">
  2 +
  3 + <div class="table-responsive" ng-if="vm.loading">
  4 + <div class="table-responsive">Carregando...</div>
  5 + </div>
  6 + <div class="table-responsive" ng-if="!vm.loading && vm.proposals">
  7 + <table class="table table-striped">
  8 + <thead>
  9 + <tr>
  10 + <th>
  11 + Colocação
  12 + <button type="button" class="btn btn-link btn-question">?</button>
  13 + </th>
  14 + <th>123 PROPOSTAS</th>
  15 + </tr>
  16 + </thead>
  17 + <tbody>
  18 + <tr ng-repeat="proposal in vm.proposals">
  19 +
  20 + <td class="color-theme-fg">
  21 + <span class="position">{{::($index+1)}}º</span>
  22 + </td>
  23 + <td>
  24 + <div class="row">
  25 + <div class="col-xs-12">
  26 + <span class="abstract">{{proposal.abstract}}</span>
  27 + </div>
  28 + </div>
  29 + <div class="row row-actions">
  30 + <div class="col-md-9">
  31 + <button type="button" class="btn btn-link btn-rate color-theme-common-fg">
  32 + Avalie esta proposta
  33 + <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
  34 + </button>
  35 + </div>
  36 + <div class="col-md-3">
  37 + <proposal-stats views="{{::proposal.hits}}" up="{{::proposal.votes_for}}" down="{{::proposal.votes_against}}"></proposal-stats>
  38 + </div>
  39 + </div>
  40 + </td>
  41 + </tr>
  42 + </tbody>
  43 + </table>
  44 + </div>
  45 +</div>
src/app/components/proposal-list/proposal-list.scss 0 → 100644
@@ -0,0 +1,94 @@ @@ -0,0 +1,94 @@
  1 +.proposal-list {
  2 + table {
  3 + border-radius: 4px;
  4 + overflow: hidden;
  5 + }
  6 +
  7 + thead {
  8 + th{
  9 + color: #fff;
  10 + background-color: #606060;
  11 + &:first-child {
  12 + background-color: #484848;
  13 + text-align: right;
  14 + width: 160px;
  15 + padding-right: 20px;
  16 + }
  17 + }
  18 +
  19 + .btn-question {
  20 + color: #484848;
  21 + background-color: #fff;
  22 + display: inline-block;
  23 + text-align: center;
  24 + width: 22px;
  25 + height: 22px;
  26 + margin-left: 10px;
  27 + padding: 0;
  28 + border-radius: 100%;
  29 + }
  30 +
  31 + .popover {
  32 + color: #484848;
  33 + }
  34 + }
  35 +
  36 + tbody {
  37 + tr {
  38 + background-color: #fff;
  39 + }
  40 +
  41 + td {
  42 + &:first-child {
  43 + font-size: 22px;
  44 + font-weight: bold;
  45 + padding: 0;
  46 + text-align: right;
  47 + }
  48 + }
  49 +
  50 + .position {
  51 + display: block;
  52 + width: 100%;
  53 + margin: 20px 0;
  54 + padding: 5px 20px;
  55 + border-top-right-radius: 4px;
  56 + border-bottom-right-radius: 4px;
  57 + }
  58 + }
  59 +
  60 + .abstract {
  61 + color: #393939;
  62 + font-size: 18px;
  63 + }
  64 +
  65 + .row-actions {
  66 + padding-top: 20px;
  67 + }
  68 +
  69 + .btn-rate {
  70 + padding: 0;
  71 + font-size: 20px;
  72 + font-weight: bold;
  73 + text-decoration: blink;
  74 + }
  75 +
  76 + // override bootstrap
  77 + .table-striped > tbody > tr:nth-of-type(odd) {
  78 + // impar
  79 + background-color: #eaeaea;
  80 +
  81 + .position {
  82 + background-color: #fff;
  83 + }
  84 + }
  85 +
  86 + .table-striped > tbody > tr:nth-of-type(even) {
  87 + // par
  88 + background-color: #fff;
  89 +
  90 + .position {
  91 + background-color: #eaeaea;
  92 + }
  93 + }
  94 +}
src/app/components/proposal-ranking/proposal-ranking-carousel.scss
@@ -1,90 +0,0 @@ @@ -1,90 +0,0 @@
1 -.proposal-ranking {  
2 - // both: carousel and list  
3 -}  
4 -  
5 -.proposal-ranking--carousel {  
6 - background-color: #f1f1f1;  
7 - border-radius: 5px;  
8 - overflow: hidden;  
9 -  
10 - &-top {  
11 - position: relative;  
12 - color: #fff;  
13 - font-weight: bold;  
14 - font-size: 25px;  
15 - padding: 20px 15px;  
16 -  
17 -  
18 - &-triggers {  
19 - position: absolute;  
20 - right: 15px;  
21 - top: 20px;  
22 -  
23 - button {  
24 - border: 1px solid #fff;  
25 - border-radius: 100%;  
26 - width: 15px;  
27 - height: 15px;  
28 - margin-right: 5px;  
29 - background-color: transparent;  
30 -  
31 - cursor: pointer;  
32 -  
33 - &.active {  
34 - background-color: #fff;  
35 - }  
36 - }  
37 - }  
38 - }  
39 -  
40 - &-middle {  
41 - position: relative;  
42 - padding: 25px 30px;  
43 - cursor: pointer;  
44 - -webkit-user-select: none;  
45 - -khtml-user-select: none;  
46 - -moz-user-select: none;  
47 - -ms-user-select: none;  
48 - user-select: none;  
49 -  
50 - .content {  
51 - position: relative;  
52 - z-index: 2;  
53 - }  
54 -  
55 - &-watermark {  
56 - position: absolute;  
57 - bottom: 1px;  
58 - left: -5px;  
59 - color: #ddd;  
60 - font-size: 150px;  
61 - font-weight: bold;  
62 - line-height: 116px;  
63 - z-index: 1;  
64 -  
65 - }  
66 - }  
67 -  
68 - &-bottom {  
69 - position: relative;  
70 - color: #fff;  
71 - padding: 10px;  
72 - font-weight: bold;  
73 - cursor: pointer;  
74 - z-index: 10;  
75 -  
76 - &-icon {  
77 - position: absolute;  
78 - top: 10px;  
79 - right: 15px;  
80 -  
81 - .glyphicon {  
82 - position: relative;  
83 - top: -2px;  
84 - background-color: #fff;  
85 - padding: 6px 5px 5px 6px;  
86 - border-radius: 100%;  
87 - }  
88 - }  
89 - }  
90 -}  
src/app/components/proposal-ranking/proposal-ranking-list.scss
@@ -1,98 +0,0 @@ @@ -1,98 +0,0 @@
1 -.proposal-ranking {  
2 - // both: carousel and list  
3 -}  
4 -  
5 -.proposal-ranking--list {  
6 - table {  
7 - border-radius: 4px;  
8 - overflow: hidden;  
9 - }  
10 -  
11 - thead {  
12 - th{  
13 - color: #fff;  
14 - background-color: #606060;  
15 - &:first-child {  
16 - background-color: #484848;  
17 - text-align: right;  
18 - width: 160px;  
19 - padding-right: 20px;  
20 - }  
21 - }  
22 -  
23 - .btn-question {  
24 - color: #484848;  
25 - background-color: #fff;  
26 - display: inline-block;  
27 - text-align: center;  
28 - width: 22px;  
29 - height: 22px;  
30 - margin-left: 10px;  
31 - padding: 0;  
32 - border-radius: 100%;  
33 - }  
34 -  
35 - .popover {  
36 - color: #484848;  
37 - }  
38 - }  
39 -  
40 - tbody {  
41 - tr {  
42 - background-color: #fff;  
43 - }  
44 -  
45 - td {  
46 - &:first-child {  
47 - font-size: 22px;  
48 - font-weight: bold;  
49 - padding: 0;  
50 - text-align: right;  
51 - }  
52 - }  
53 -  
54 - .position {  
55 - display: block;  
56 - width: 100%;  
57 - margin: 20px 0;  
58 - padding: 5px 20px;  
59 - border-top-right-radius: 4px;  
60 - border-bottom-right-radius: 4px;  
61 - }  
62 - }  
63 -  
64 - .abstract {  
65 - color: #393939;  
66 - font-size: 18px;  
67 - }  
68 -  
69 - .row-actions {  
70 - padding-top: 20px;  
71 - }  
72 -  
73 - .btn-rate {  
74 - padding: 0;  
75 - font-size: 20px;  
76 - font-weight: bold;  
77 - text-decoration: blink;  
78 - }  
79 -  
80 - // override bootstrap  
81 - .table-striped > tbody > tr:nth-of-type(odd) {  
82 - // impar  
83 - background-color: #eaeaea;  
84 -  
85 - .position {  
86 - background-color: #fff;  
87 - }  
88 - }  
89 -  
90 - .table-striped > tbody > tr:nth-of-type(even) {  
91 - // par  
92 - background-color: #fff;  
93 -  
94 - .position {  
95 - background-color: #eaeaea;  
96 - }  
97 - }  
98 -}  
src/app/components/proposal-ranking/proposal-ranking.directive.js
@@ -1,143 +0,0 @@ @@ -1,143 +0,0 @@
1 -(function() {  
2 - 'use strict';  
3 -  
4 - angular  
5 - .module('dialoga')  
6 - .directive('proposalRanking', proposalRanking);  
7 -  
8 - /** @ngInject */  
9 - function proposalRanking() {  
10 -  
11 - /** @ngInject */  
12 - function ProposalRankingController(ArticleService, $scope, $element, $timeout, $log) {  
13 - $log.debug('ProposalRankingController');  
14 -  
15 - var vm = this;  
16 - vm.ArticleService = ArticleService;  
17 - vm.$scope = $scope;  
18 - vm.$element = $element;  
19 - vm.$timeout = $timeout;  
20 - vm.$log = $log;  
21 -  
22 - vm.init();  
23 - }  
24 -  
25 - ProposalRankingController.prototype.init = function () {  
26 - // initial values  
27 - var vm = this;  
28 -  
29 - vm.activeIndex = 0;  
30 - vm.loading = false;  
31 -  
32 - if(angular.isDefined(vm.limit) && angular.isString(vm.limit)){  
33 - vm.limit = parseInt(vm.limit);  
34 - }else{  
35 - vm.limit = 3;  
36 - }  
37 -  
38 - vm.loadData();  
39 - };  
40 -  
41 - ProposalRankingController.prototype.loadData = function () {  
42 - // async values  
43 - var vm = this;  
44 -  
45 - vm.loading = true;  
46 -  
47 - // simulate delay  
48 - vm.$timeout(function(){  
49 - vm.loading = false;  
50 -  
51 - // Fake Data  
52 - // vm.proposals = vm.ArticleService.getProposals();  
53 - vm.proposals = [{  
54 - id: 4159,  
55 - abstract: 'Ut odio unde porro in. Aut fuga magni adipisci. Recusandae ipsum distinctio omnis ut illum.',  
56 - effective_support: 0.1572052401746725,  
57 - hits: 4159,  
58 - votes_against: 3779,  
59 - votes_for: 1780  
60 - },{  
61 - id: 935,  
62 - abstract: 'Aut fuga magni adipisci. Recusandae ipsum distinctio omnis ut illum. Magni sunt ut molestiae.',  
63 - effective_support: 0.1572052401746725,  
64 - hits: 8602,  
65 - votes_against: 7005,  
66 - votes_for: 8728  
67 - },{  
68 - id: 1008,  
69 - abstract: 'Recusandae ipsum distinctio omnis ut illum. Magni sunt ut molestiae. Aut fuga magni adipisci.',  
70 - effective_support: 0.1572052401746725,  
71 - hits: 9181,  
72 - votes_against: 612,  
73 - votes_for: 1786  
74 - }];  
75 -  
76 - if(vm.display === 'list'){  
77 - // wait until DOM be created  
78 - vm.$timeout(function(){  
79 - attachPopover.call(vm);  
80 - }, 20);  
81 - }  
82 - }, 2000);  
83 - };  
84 -  
85 - ProposalRankingController.prototype.swipeLeft = function () {  
86 - var vm = this;  
87 -  
88 - vm.activeIndex = (vm.activeIndex < vm.limit - 1) ? ++vm.activeIndex : 0;  
89 - };  
90 -  
91 - ProposalRankingController.prototype.swipeRight = function () {  
92 - var vm = this;  
93 -  
94 - vm.activeIndex = (vm.activeIndex > 0) ? --vm.activeIndex : vm.limit - 1;  
95 - };  
96 -  
97 - ProposalRankingController.prototype.switchProposal = function (index) {  
98 - var vm = this;  
99 -  
100 - if(index >= 0 && index < vm.limit) {  
101 - vm.activeIndex = index;  
102 - }else{  
103 - vm.$log.warn('[switchProposal] "index" not handled:', index);  
104 - }  
105 - };  
106 -  
107 - ProposalRankingController.prototype.showProposals = function () {  
108 - var vm = this;  
109 -  
110 - // notify parents - handled by parents  
111 - vm.$scope.$emit('see-proposals');  
112 - };  
113 -  
114 - function attachPopover(){  
115 - var vm = this;  
116 -  
117 - vm.popover = angular.element(vm.$element.find('.btn-question'));  
118 - vm.popover.popover({  
119 - html: true,  
120 - placement: 'top',  
121 - animation: true,  
122 - title: 'Regra de posição das propostas',  
123 - content: '<p>É calculada pelo saldo de interações das propostas (curtidas - não curtidas) dividido pela diferença de exibições entre elas.</p><p>O objetivo dessa correção é compensar o saldo de interações e a diferença de exibições das propostas que não tiveram muitas oportunidades de visualização ou das propostas que tiveram mais oportunidades de visualização que a média.</p><p>Com essa correção, é possível comparar propostas que entraram em diferentes momentos, durante todo o período da consulta.</p>'  
124 - });  
125 - }  
126 -  
127 - var directive = {  
128 - restrict: 'E',  
129 - templateUrl: 'app/components/proposal-ranking/proposal-ranking.html',  
130 - scope: {  
131 - limit: '&',  
132 - display: '='  
133 - },  
134 - controller: ProposalRankingController,  
135 - controllerAs: 'vm',  
136 - bindToController: true  
137 - };  
138 -  
139 -  
140 - return directive;  
141 - }  
142 -  
143 -})();  
src/app/components/proposal-ranking/proposal-ranking.html
@@ -1,84 +0,0 @@ @@ -1,84 +0,0 @@
1 -<div class="proposal-ranking contraste-box">  
2 - <div class="proposal-ranking--carousel" ng-if="vm.display === 'carousel'">  
3 - <div ng-if="!vm.proposals">  
4 - Carregando...  
5 - </div>  
6 - <div ng-if="vm.proposals">  
7 - <div class="proposal-ranking--carousel-top color-theme-bg">  
8 - <div class="proposal-ranking--carousel-position" ng-repeat="proposal in vm.proposals">  
9 - <span ng-show="vm.activeIndex === $index">{{::($index+1)}}º</span>  
10 - <span ng-show="vm.activeIndex === $index">Lugar</span>  
11 - </div>  
12 - <div class="proposal-ranking--carousel-top-triggers" ng-if="vm.proposals">  
13 - <ul class="list-inline">  
14 - <li class="item-dot" ng-repeat="proposal in vm.proposals">  
15 - <button type="button" ng-class="{'active': vm.activeIndex === $index}" ng-click="vm.switchProposal($index)" title="Apersentar proposta na posição {{$index}}"></button>  
16 - </li>  
17 - </ul>  
18 - </div>  
19 - </div>  
20 - <div class="proposal-ranking--carousel-middle" ng-swipe-left="vm.swipeLeft()" ng-swipe-right="vm.swipeRight()">  
21 - <div ng-repeat="proposal in vm.proposals" class="animation-swipe">  
22 - <div class="content">  
23 - <div ng-show="vm.activeIndex === $index">{{::proposal.abstract}}</div>  
24 - </div>  
25 - <div class="proposal-ranking--carousel-middle-watermark" ng-show="vm.activeIndex === $index">  
26 - <span>{{::($index+1)}}º</span>  
27 - </div>  
28 - </div>  
29 - </div>  
30 - <div class="proposal-ranking--carousel-bottom color-theme-common-bg" ng-click="vm.showProposals()">  
31 - <div>Veja as propostas mais vortadas</div>  
32 - <div class="proposal-ranking--carousel-bottom-icon">  
33 - <span class="glyphicon glyphicon-chevron-down pull-right color-theme-common-fg"></span>  
34 - </div>  
35 - </div>  
36 - </div>  
37 - </div>  
38 -  
39 - <div class="proposal-ranking--list" ng-if="vm.display==='list'">  
40 -  
41 - <div class="table-responsive" ng-if="vm.loading">  
42 - <div class="table-responsive">Carregando...</div>  
43 - </div>  
44 - <div class="table-responsive" ng-if="!vm.loading && vm.proposals">  
45 - <table class="table table-striped">  
46 - <thead>  
47 - <tr>  
48 - <th>  
49 - Colocação  
50 - <button type="button" class="btn btn-link btn-question">?</button>  
51 - </th>  
52 - <th>123 PROPOSTAS</th>  
53 - </tr>  
54 - </thead>  
55 - <tbody>  
56 - <tr ng-repeat="proposal in vm.proposals">  
57 -  
58 - <td class="color-theme-fg">  
59 - <span class="position">{{::($index+1)}}º</span>  
60 - </td>  
61 - <td>  
62 - <div class="row">  
63 - <div class="col-xs-12">  
64 - <span class="abstract">{{proposal.abstract}}</span>  
65 - </div>  
66 - </div>  
67 - <div class="row row-actions">  
68 - <div class="col-md-9">  
69 - <button type="button" class="btn btn-link btn-rate color-theme-common-fg">  
70 - Avalie esta proposta  
71 - <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>  
72 - </button>  
73 - </div>  
74 - <div class="col-md-3">  
75 - <proposal-stats views="{{::proposal.hits}}" up="{{::proposal.votes_for}}" down="{{::proposal.votes_against}}"></proposal-stats>  
76 - </div>  
77 - </div>  
78 - </td>  
79 - </tr>  
80 - </tbody>  
81 - </table>  
82 - </div>  
83 - </div>  
84 -</div>  
src/app/components/proposal-related/proposal-related.directive.js
@@ -76,7 +76,7 @@ @@ -76,7 +76,7 @@
76 if(vm.display === 'list'){ 76 if(vm.display === 'list'){
77 // wait until DOM be created 77 // wait until DOM be created
78 vm.$timeout(function(){ 78 vm.$timeout(function(){
79 - attachPopover.call(vm); 79 + // attachPopover.call(vm);
80 }, 20); 80 }, 20);
81 } 81 }
82 }, 2000); 82 }, 2000);
src/app/components/service/utils.service.js
@@ -1,78 +0,0 @@ @@ -1,78 +0,0 @@
1 -(function() {  
2 - 'use strict';  
3 -  
4 - angular  
5 - .module('dialoga')  
6 - .factory('UtilService', UtilService);  
7 -  
8 - /** @ngInject */  
9 - function UtilService($http, $q, $log) {  
10 - $log.debug('UtilService');  
11 -  
12 - var service = {  
13 - get: get,  
14 - post: post,  
15 - // put: put,  
16 - // delete: delete,  
17 - // head: head,  
18 - handleSuccess: handleSuccess,  
19 - handleError: handleError  
20 - };  
21 -  
22 - return service;  
23 -  
24 - function get (url, config) {  
25 - return $http.get(url, config)  
26 - .then(handleSuccess)  
27 - .catch(handleError);  
28 - }  
29 -  
30 - function post (url, config) {  
31 - return $http.post(url, config)  
32 - .then(handleSuccess)  
33 - .catch(handleError);  
34 - }  
35 -  
36 - /**  
37 - * Transform the successful response, unwrapping the application data  
38 - * from the API response payload.  
39 - *  
40 - * @param {Object} response from the server.  
41 - * data – {string|Object} – The response body transformed with the transform functions.  
42 - * status – {number} – HTTP status code of the response.  
43 - * headers – {function([headerName])} – Header getter function.  
44 - * config – {Object} – The configuration object that was used to generate the request.  
45 - * statusText – {string} – HTTP status text of the response.  
46 - *  
47 - * @return {Object} the data unwrapped.  
48 - */  
49 - function handleSuccess (response) {  
50 - $log.debug('[SUCCESS]', response);  
51 - return response.data;  
52 - }  
53 -  
54 - /**  
55 - * Transform the error response, unwrapping the application data from  
56 - * the API response payload.  
57 - *  
58 - * @param {Object} error from the server.  
59 - * @return {Promise} promise rejection called.  
60 - */  
61 - function handleError (error) {  
62 - $log.debug('[ERROR]', error);  
63 -  
64 - $log.error('XHR Failed on Service.\n' + angular.toJson(error.data, true));  
65 -  
66 - // The API response from the server should be returned in a  
67 - // nomralized format. However, if the request was not handled by the  
68 - // server (or what not handles properly - ex. server error), then we  
69 - // may have to normalize it on our end, as best we can.  
70 - if (!angular.isObject(error.data) || !error.data.message) {  
71 - return $q.reject('An unknown error occurred.');  
72 - }  
73 -  
74 - // Otherwise, use expected error message.  
75 - return $q.reject(error.data.message);  
76 - }  
77 - }  
78 -})();  
src/app/components/service/utils.service.spec.js
@@ -1,28 +0,0 @@ @@ -1,28 +0,0 @@
1 -(function() {  
2 - 'use strict';  
3 -  
4 - describe('util services', function() {  
5 - // var UtilService, httpBackend;  
6 -  
7 - // beforeEach(module('dialoga'));  
8 -  
9 - // beforeEach(inject(function(_UtilService_, $httpBackend) {  
10 - // UtilService = _UtilService_;  
11 - // httpBackend = $httpBackend;  
12 - // }));  
13 -  
14 - // it('should do something', function() {  
15 - // var url = 'http://example.com/api/v1/data/103358';  
16 - // httpBackend.whenGET(url).respond({});  
17 -  
18 - // UtilService.getData().then(function(result) {  
19 -  
20 - // expect(result.data).toBeDefined();  
21 - // expect(result.data.title).toEqual('My Title');  
22 -  
23 - // });  
24 -  
25 - // httpBackend.flush();  
26 - // });  
27 - });  
28 -})();  
src/app/components/socialShare/socialShare.directive.js
@@ -23,7 +23,7 @@ @@ -23,7 +23,7 @@
23 function SocialShareController($log) { 23 function SocialShareController($log) {
24 $log.debug('SocialShareController'); 24 $log.debug('SocialShareController');
25 25
26 - var vm = this; 26 + // var vm = this;
27 } 27 }
28 } 28 }
29 29
src/app/components/socialShare/socialShare.scss
@@ -21,8 +21,4 @@ @@ -21,8 +21,4 @@
21 text-align: right; 21 text-align: right;
22 vertical-align: middle; 22 vertical-align: middle;
23 } 23 }
24 -  
25 - .icon {  
26 - display: block;  
27 - }  
28 } 24 }
src/app/components/topic-list/topic-list.directive.js 0 → 100644
@@ -0,0 +1,316 @@ @@ -0,0 +1,316 @@
  1 +(function() {
  2 + 'use strict';
  3 +
  4 + angular
  5 + .module('dialoga')
  6 + .directive('topicList', topicList);
  7 +
  8 + /** @ngInject */
  9 + function topicList() {
  10 +
  11 + /** @ngInject */
  12 + function TopicListController($scope, $element, $location, $filter, $log) {
  13 + $log.debug('TopicListController');
  14 +
  15 + // alias
  16 + var vm = this;
  17 +
  18 + // dependencies
  19 + vm.$scope = $scope;
  20 + vm.$element = $element;
  21 + vm.$location = $location;
  22 + vm.$filter = $filter;
  23 + vm.$log = $log;
  24 + vm.defaultLimit = 6;
  25 +
  26 + // initialization
  27 + vm.init();
  28 + }
  29 +
  30 + TopicListController.prototype.init = function() {
  31 + var vm = this;
  32 +
  33 + if (!vm.article) {
  34 + vm.$log.warn('no article to display. Tip: use a ng-if before use this directive');
  35 + return;
  36 + }
  37 +
  38 + vm.categories = vm.article.categories;
  39 + vm.programs = vm.article.children;
  40 + vm.orderCriteries = [
  41 + { label: 'Título', name: 'titulo' },
  42 + { label: 'Tema', name: 'tema' },
  43 + { label: 'Aleatório', name: 'aleatorio' }
  44 + ];
  45 +
  46 + vm.filtredProgramList = vm.getFiltredPrograms();
  47 + vm.search = vm.$location.search();
  48 +
  49 + // Add initial values for the filter
  50 + vm.query = (vm.search && vm.search.filtro) ? vm.search.filtro : null;
  51 + vm.limitTo = (vm.search && vm.search.limite) ? parseInt(vm.search.limite, 10) : vm.defaultLimit;
  52 + vm.categoryFilter = (vm.search && vm.search.tema) ? vm.getCategoryBySlug(vm.search.tema) : null;
  53 + vm.orderCriteria = (vm.search && vm.search.ordem) ? { name: vm.search.ordem } : null;
  54 + vm.reverse = (vm.search && vm.search.reverso) ? true : false;
  55 +
  56 + if (!angular.equals({}, vm.search)) {
  57 + var $el = vm.$element;
  58 + angular.element('body').animate({scrollTop: $el.offset().top}, 'slow');
  59 + }
  60 +
  61 + // update window location params
  62 + vm.$scope.$watch('vm.query', function(newValue/*, oldValue*/) {
  63 + vm.search.filtro = newValue ? newValue : null;
  64 + vm.$location.search('filtro', vm.search.filtro);
  65 + if(vm.search.filtro){
  66 + vm.limitTo = vm.programs.length;
  67 + }else{
  68 + vm.limitTo = vm.defaultLimit;
  69 + }
  70 + vm.filtredProgramList = vm.getFiltredPrograms();
  71 + });
  72 +
  73 + vm.$scope.$watch('vm.limitTo', function(newValue/*, oldValue*/) {
  74 + vm.search.limite = (newValue && newValue !== vm.defaultLimit) ? newValue : null;
  75 + vm.$location.search('limite', vm.search.limite);
  76 + vm.filtredProgramList = vm.getFiltredPrograms();
  77 + });
  78 +
  79 + vm.$scope.$watch('vm.categoryFilter', function(newValue/*, oldValue*/) {
  80 + vm.search.tema = newValue ? newValue.slug : null;
  81 + vm.$location.search('tema', vm.search.tema);
  82 + if(vm.search.tema){
  83 + vm.limitTo = vm.programs.length;
  84 + }
  85 + vm.filtredProgramList = vm.getFiltredPrograms();
  86 + });
  87 +
  88 + vm.$scope.$watch('vm.orderCriteria', function(newValue/*, oldValue*/) {
  89 + vm.search.ordem = (newValue && newValue.name) ? newValue.name : null;
  90 + vm.$location.search('ordem', vm.search.ordem);
  91 + vm.filtredProgramList = vm.getFiltredPrograms();
  92 + });
  93 +
  94 + vm.$scope.$watch('vm.reverse', function(newValue/*, oldValue*/) {
  95 + vm.search.reverso = newValue ? newValue : null;
  96 + vm.$location.search('reverso', vm.search.reverso);
  97 + vm.filtredProgramList = vm.getFiltredPrograms();
  98 + });
  99 +
  100 + };
  101 +
  102 + TopicListController.prototype.resetFilterValues = function() {
  103 + var vm = this;
  104 +
  105 + vm.query = null;
  106 + vm.limitTo = vm.defaultLimit;
  107 + vm.categoryFilter = null;
  108 + vm.orderCriteria = null;
  109 + };
  110 +
  111 + TopicListController.prototype.getIconClasses = function(category) {
  112 + var vm = this;
  113 +
  114 + vm.$log.debug('[TODO] getIconClasses of category:', category);
  115 + return 'glyphicon glyphicon-exclamation-sign';
  116 + };
  117 +
  118 + TopicListController.prototype.getCategoryBySlug = function(categorySlug) {
  119 + var vm = this;
  120 + var result = null;
  121 +
  122 + angular.forEach(vm.categories, function(value/*, key*/) {
  123 + if (value.slug === categorySlug) {
  124 + result = value;
  125 + }
  126 + });
  127 +
  128 + return result;
  129 + };
  130 +
  131 + TopicListController.prototype.filterByCategory = function(category, $event) {
  132 + var vm = this;
  133 +
  134 + $event.stopPropagation();
  135 +
  136 + if (category !== vm.categoryFilter) {
  137 +
  138 + // selected new filter
  139 + vm.categoryFilter = category;
  140 + } else {
  141 + vm.categoryFilter = null;
  142 + }
  143 + };
  144 +
  145 + TopicListController.prototype.showAll = function($event) {
  146 + var vm = this;
  147 +
  148 + $event.stopPropagation();
  149 +
  150 + vm.resetFilterValues();
  151 + vm.limitTo = vm.programs.length;
  152 + };
  153 +
  154 + TopicListController.prototype.getFiltredPrograms = function() {
  155 + var vm = this;
  156 +
  157 + var input = vm.programs;
  158 + var output = input;
  159 + var query = vm.query;
  160 + var categoryFilter = vm.categoryFilter;
  161 + var orderCriteria = vm.orderCriteria ? vm.orderCriteria : { name : 'aleatorio'};
  162 + var filter = vm.$filter('filter');
  163 + var orderBy = vm.$filter('orderBy');
  164 + var limitTo = vm.$filter('limitTo');
  165 + var limit = vm.limitTo ? vm.limitTo : 4;
  166 +
  167 + if (categoryFilter) {
  168 + output = _filterByCategory(output, categoryFilter);
  169 + }
  170 +
  171 + if (query) {
  172 + output = filter(output, query, false);
  173 + }
  174 +
  175 + switch (orderCriteria.name) {
  176 + case 'titulo':
  177 + output = orderBy(output, 'title', vm.reverse);
  178 + break;
  179 + case 'tema':
  180 + output = orderBy(output, 'categories[0].name', vm.reverse);
  181 + break;
  182 + case 'more_participants':
  183 + vm.$log.info('Criteria not handled yet: ', orderCriteria);
  184 + break;
  185 + case 'aleatorio':
  186 + // shuffling
  187 + // if (!vm._isShuffled){
  188 + output = vm.filterShuffle(output);
  189 + // vm._isShuffled = true;
  190 + // }
  191 +
  192 + if (vm.reverse) {
  193 + output = output.slice().reverse();
  194 + }
  195 +
  196 + break;
  197 + default:
  198 + vm.$log.warn('Criteria not matched: ', orderCriteria);
  199 + break;
  200 + }
  201 +
  202 + output = limitTo(output, limit);
  203 +
  204 + return output;
  205 + };
  206 +
  207 + TopicListController.prototype.filterShuffle = function(input) {
  208 + var result = [];
  209 + var resultByCategory = {};
  210 +
  211 + // divide by categories
  212 + for (var i = 0; i < input.length; i++) {
  213 + var program = input[i];
  214 + var categorySlug = program.categories[0].slug;
  215 +
  216 + if (!resultByCategory[categorySlug]) {
  217 + resultByCategory[categorySlug] = [];
  218 + }
  219 +
  220 + resultByCategory[categorySlug].push(program);
  221 + }
  222 +
  223 + // shuffle each array
  224 + var prop = null;
  225 + var categoryWithPrograms = null;
  226 + for (prop in resultByCategory) {
  227 + if (resultByCategory.hasOwnProperty(prop)) {
  228 + categoryWithPrograms = resultByCategory[prop];
  229 + resultByCategory[prop] = shuffle(categoryWithPrograms);
  230 + }
  231 + }
  232 +
  233 + // Concat all into result array
  234 + // > while has program at Lists on resultByCategory
  235 + var hasProgram = true;
  236 + while (hasProgram) {
  237 +
  238 + var foundProgram = false;
  239 + // each categoryList with array of program
  240 + prop = null;
  241 + categoryWithPrograms = null;
  242 + for (prop in resultByCategory) {
  243 +
  244 + if (resultByCategory.hasOwnProperty(prop)) {
  245 + categoryWithPrograms = resultByCategory[prop];
  246 +
  247 + if (categoryWithPrograms.length > 0) {
  248 + var pivotProgram = categoryWithPrograms.pop();
  249 + result.push(pivotProgram);
  250 + foundProgram = true;
  251 + }
  252 + }
  253 + }
  254 +
  255 + if (!foundProgram) {
  256 + hasProgram = false;
  257 + }
  258 + }
  259 +
  260 + return result;
  261 + };
  262 +
  263 + var directive = {
  264 + restrict: 'E',
  265 + templateUrl: 'app/components/programas/programas.html',
  266 + scope: {
  267 + article: '='
  268 + },
  269 + controller: TopicListController,
  270 + controllerAs: 'vm',
  271 + bindToController: true
  272 + };
  273 +
  274 + return directive;
  275 + }
  276 +
  277 + function _filterByCategory (input, category) {
  278 + input = input || [];
  279 +
  280 + if (!category) {
  281 + // no filter
  282 + return input;
  283 + }
  284 +
  285 + var out = [];
  286 + for (var i = 0; i < input.length; i++) {
  287 + var program = input[i];
  288 + if (program.categories[0].slug === category.slug) {
  289 + out.push(program);
  290 + }
  291 + }
  292 +
  293 + return out;
  294 + }
  295 +
  296 + // -> Fisher–Yates shuffle algorithm
  297 + function shuffle (array) {
  298 + var currentIndex = array.length, temporaryValue, randomIndex ;
  299 +
  300 + // While there remain elements to shuffle...
  301 + while (0 !== currentIndex) {
  302 +
  303 + // Pick a remaining element...
  304 + randomIndex = Math.floor(Math.random() * currentIndex);
  305 + currentIndex -= 1;
  306 +
  307 + // And swap it with the current element.
  308 + temporaryValue = array[currentIndex];
  309 + array[currentIndex] = array[randomIndex];
  310 + array[randomIndex] = temporaryValue;
  311 + }
  312 +
  313 + return array;
  314 + }
  315 +
  316 +})();
src/app/components/topic-list/topic-list.directive.spec.js 0 → 100644
@@ -0,0 +1,32 @@ @@ -0,0 +1,32 @@
  1 +(function() {
  2 + 'use strict';
  3 +
  4 + describe('topic directive', function() {
  5 + var compile, scope, directiveElem;
  6 +
  7 + beforeEach(function(){
  8 + module('dialoga');
  9 +
  10 + inject(function($compile, $rootScope){
  11 + compile = $compile;
  12 + scope = $rootScope.$new();
  13 + // mock topics
  14 + scope.topics = [];
  15 + });
  16 +
  17 + directiveElem = getCompiledElement();
  18 + });
  19 +
  20 + function getCompiledElement(){
  21 + var element = compile(angular.element('<topic-list></topic-list>'))(scope);
  22 + var compiledElement = compile(element)(scope);
  23 + scope.$digest();
  24 + return compiledElement;
  25 + }
  26 +
  27 + // it('ensure exist only one id "topic-list"', function() {});
  28 +
  29 + // it('should show default topics, one each category', function() {});
  30 +
  31 + });
  32 +})();
src/app/components/util-service/utils.service.js 0 → 100644
@@ -0,0 +1,78 @@ @@ -0,0 +1,78 @@
  1 +(function() {
  2 + 'use strict';
  3 +
  4 + angular
  5 + .module('dialoga')
  6 + .factory('UtilService', UtilService);
  7 +
  8 + /** @ngInject */
  9 + function UtilService($http, $q, $log) {
  10 + $log.debug('UtilService');
  11 +
  12 + var service = {
  13 + get: get,
  14 + post: post,
  15 + // put: put,
  16 + // delete: delete,
  17 + // head: head,
  18 + handleSuccess: handleSuccess,
  19 + handleError: handleError
  20 + };
  21 +
  22 + return service;
  23 +
  24 + function get (url, config) {
  25 + return $http.get(url, config)
  26 + .then(handleSuccess)
  27 + .catch(handleError);
  28 + }
  29 +
  30 + function post (url, config) {
  31 + return $http.post(url, config)
  32 + .then(handleSuccess)
  33 + .catch(handleError);
  34 + }
  35 +
  36 + /**
  37 + * Transform the successful response, unwrapping the application data
  38 + * from the API response payload.
  39 + *
  40 + * @param {Object} response from the server.
  41 + * data – {string|Object} – The response body transformed with the transform functions.
  42 + * status – {number} – HTTP status code of the response.
  43 + * headers – {function([headerName])} – Header getter function.
  44 + * config – {Object} – The configuration object that was used to generate the request.
  45 + * statusText – {string} – HTTP status text of the response.
  46 + *
  47 + * @return {Object} the data unwrapped.
  48 + */
  49 + function handleSuccess (response) {
  50 + $log.debug('[SUCCESS]', response);
  51 + return response.data;
  52 + }
  53 +
  54 + /**
  55 + * Transform the error response, unwrapping the application data from
  56 + * the API response payload.
  57 + *
  58 + * @param {Object} error from the server.
  59 + * @return {Promise} promise rejection called.
  60 + */
  61 + function handleError (error) {
  62 + $log.debug('[ERROR]', error);
  63 +
  64 + $log.error('XHR Failed on Service.\n' + angular.toJson(error.data, true));
  65 +
  66 + // The API response from the server should be returned in a
  67 + // nomralized format. However, if the request was not handled by the
  68 + // server (or what not handles properly - ex. server error), then we
  69 + // may have to normalize it on our end, as best we can.
  70 + if (!angular.isObject(error.data) || !error.data.message) {
  71 + return $q.reject('An unknown error occurred.');
  72 + }
  73 +
  74 + // Otherwise, use expected error message.
  75 + return $q.reject(error.data.message);
  76 + }
  77 + }
  78 +})();
src/app/components/util-service/utils.service.spec.js 0 → 100644
@@ -0,0 +1,28 @@ @@ -0,0 +1,28 @@
  1 +(function() {
  2 + 'use strict';
  3 +
  4 + describe('util services', function() {
  5 + // var UtilService, httpBackend;
  6 +
  7 + // beforeEach(module('dialoga'));
  8 +
  9 + // beforeEach(inject(function(_UtilService_, $httpBackend) {
  10 + // UtilService = _UtilService_;
  11 + // httpBackend = $httpBackend;
  12 + // }));
  13 +
  14 + // it('should do something', function() {
  15 + // var url = 'http://example.com/api/v1/data/103358';
  16 + // httpBackend.whenGET(url).respond({});
  17 +
  18 + // UtilService.getData().then(function(result) {
  19 +
  20 + // expect(result.data).toBeDefined();
  21 + // expect(result.data.title).toEqual('My Title');
  22 +
  23 + // });
  24 +
  25 + // httpBackend.flush();
  26 + // });
  27 + });
  28 +})();
src/app/index.route.js
@@ -194,9 +194,18 @@ @@ -194,9 +194,18 @@
194 'footer': { templateUrl: 'app/pages/footer/footer.html' } 194 'footer': { templateUrl: 'app/pages/footer/footer.html' }
195 } 195 }
196 }) 196 })
  197 + .state('erro', {
  198 + url: '/erro',
  199 + ncyBreadcrumb: {label: 'Erro'},
  200 + views: {
  201 + 'header': { templateUrl: 'app/pages/header/header.html' },
  202 + 'main': { templateUrl: 'app/pages/erro/erro.html' },
  203 + 'footer': { templateUrl: 'app/pages/footer/footer.html' }
  204 + }
  205 + })
197 ; 206 ;
198 207
199 - $urlRouterProvider.otherwise('/'); 208 + $urlRouterProvider.otherwise('/erro');
200 } 209 }
201 210
202 })(); 211 })();
src/app/index.scss
@@ -132,6 +132,10 @@ body { @@ -132,6 +132,10 @@ body {
132 } 132 }
133 } 133 }
134 134
  135 +.icon {
  136 + display: block;
  137 +}
  138 +
135 .icon-wrapper-rounded { 139 .icon-wrapper-rounded {
136 padding: 3px; 140 padding: 3px;
137 border-radius: 100%; 141 border-radius: 100%;
src/app/layout.scss
1 .row-height { 1 .row-height {
2 - display: table;  
3 - table-layout: fixed;  
4 - height: 100%;  
5 - width: 100%; 2 + display: table;
  3 + table-layout: fixed;
  4 + height: 100%;
  5 + width: 100%;
  6 +}
6 7
7 - @media (max-width: $screen-sm) {  
8 - display: block;  
9 - } 8 +.col-height {
  9 + display: table-cell;
  10 + float: none;
  11 + height: 100%;
  12 +}
10 13
11 - // @media (min-width: $screen-sm + 1) {  
12 - // height: $hLine * 2;  
13 - // } 14 +.col-top {
  15 + vertical-align: top;
  16 +}
14 17
15 - // @media (min-width: $screen-md + 1) {  
16 - // height: $hLine * 2;  
17 - // } 18 +.col-middle {
  19 + vertical-align: middle;
18 } 20 }
19 21
20 -.col-height { 22 +.col-bottom {
  23 + vertical-align: bottom;
  24 +}
  25 +
  26 +@media (min-width: 480px) {
  27 + .row-xs-height {
  28 + display: table;
  29 + table-layout: fixed;
  30 + height: 100%;
  31 + width: 100%;
  32 + }
  33 + .col-xs-height {
21 display: table-cell; 34 display: table-cell;
22 float: none; 35 float: none;
23 height: 100%; 36 height: 100%;
  37 + }
  38 + .col-xs-top {
24 vertical-align: top; 39 vertical-align: top;
  40 + }
  41 + .col-xs-middle {
  42 + vertical-align: middle;
  43 + }
  44 + .col-xs-bottom {
  45 + vertical-align: bottom;
  46 + }
25 } 47 }
26 48
27 -.col-height--align-bottom { 49 +@media (min-width: 768px) {
  50 + .row-sm-height {
  51 + display: table;
  52 + table-layout: fixed;
  53 + height: 100%;
  54 + width: 100%;
  55 + }
  56 + .col-sm-height {
  57 + display: table-cell;
  58 + float: none;
  59 + height: 100%;
  60 + }
  61 + .col-sm-top {
  62 + vertical-align: top;
  63 + }
  64 + .col-sm-middle {
  65 + vertical-align: middle;
  66 + }
  67 + .col-sm-bottom {
28 vertical-align: bottom; 68 vertical-align: bottom;
  69 + }
29 } 70 }
30 71
31 -.inside {  
32 - margin-top: 20px;  
33 - margin-bottom: 20px; 72 +@media (min-width: 992px) {
  73 + .row-md-height {
  74 + display: table;
  75 + table-layout: fixed;
  76 + height: 100%;
  77 + width: 100%;
  78 + }
  79 + .col-md-height {
  80 + display: table-cell;
  81 + float: none;
  82 + height: 100%;
  83 + }
  84 + .col-md-top {
  85 + vertical-align: top;
  86 + }
  87 + .col-md-middle {
  88 + vertical-align: middle;
  89 + }
  90 + .col-md-bottom {
  91 + vertical-align: bottom;
  92 + }
34 } 93 }
35 94
36 -.inside-full-height { 95 +@media (min-width: 1200px) {
  96 + .row-lg-height {
  97 + display: table;
  98 + table-layout: fixed;
37 height: 100%; 99 height: 100%;
38 - margin-top: 0;  
39 - margin-bottom: 0;  
40 -  
41 -  
42 - @media (max-width: $screen-sm) {  
43 - border: 1px solid;  
44 - border-radius: 3px;  
45 - padding: 20px;  
46 - margin: 10px 0;  
47 -  
48 - @each $category, $color in $categories {  
49 - .#{$category} & {  
50 - border-color: $color;  
51 - }  
52 - }  
53 - } 100 + width: 100%;
  101 + }
  102 + .col-lg-height {
  103 + display: table-cell;
  104 + float: none;
  105 + height: 100%;
  106 + }
  107 + .col-lg-top {
  108 + vertical-align: top;
  109 + }
  110 + .col-lg-middle {
  111 + vertical-align: middle;
  112 + }
  113 + .col-lg-bottom {
  114 + vertical-align: bottom;
  115 + }
54 } 116 }
55 117
56 .has-error { 118 .has-error {
src/app/pages/article/article.controller.js
@@ -6,11 +6,11 @@ @@ -6,11 +6,11 @@
6 .controller('ArticlePageController', ArticlePageController); 6 .controller('ArticlePageController', ArticlePageController);
7 7
8 /** @ngInject */ 8 /** @ngInject */
9 - function ArticlePageController(ArticleService, $state, $sce, $log) { 9 + function ArticlePageController(DialogaService, $state, $sce, $log) {
10 $log.debug('ArticlePageController'); 10 $log.debug('ArticlePageController');
11 11
12 var vm = this; 12 var vm = this;
13 - vm.ArticleService = ArticleService; 13 + vm.DialogaService = DialogaService;
14 vm.$state = $state; 14 vm.$state = $state;
15 vm.$sce = $sce; 15 vm.$sce = $sce;
16 vm.$log = $log; 16 vm.$log = $log;
@@ -26,10 +26,10 @@ @@ -26,10 +26,10 @@
26 vm.loading = true; 26 vm.loading = true;
27 switch (vm.page){ 27 switch (vm.page){
28 case 'sobre': 28 case 'sobre':
29 - vm.ArticleService.getAbout(handleSuccess, handleError); 29 + vm.DialogaService.getAbout(handleSuccess, handleError);
30 break; 30 break;
31 case 'termos-de-uso': 31 case 'termos-de-uso':
32 - vm.ArticleService.getTerms(handleSuccess, handleError); 32 + vm.DialogaService.getTerms(handleSuccess, handleError);
33 break; 33 break;
34 default: 34 default:
35 vm.$log.warn('Page not handled:', vm.page); 35 vm.$log.warn('Page not handled:', vm.page);
src/app/pages/article/article.html
1 -<div class="container" role="main"> 1 +<div class="container">
  2 + <div class="row">
  3 + <div class="col-sm-12">
  4 + <div ncy-breadcrumb></div>
  5 + </div>
  6 + </div>
  7 +</div>
2 8
3 - <article-bar></article-bar> 9 +<div class="container" role="main">
4 10
5 <div ng-if="pageArticle.loading"> 11 <div ng-if="pageArticle.loading">
6 <div class="alert alert-info"> 12 <div class="alert alert-info">
src/app/pages/article/article.service.js
@@ -1,173 +0,0 @@ @@ -1,173 +0,0 @@
1 -(function() {  
2 - 'use strict';  
3 -  
4 - angular  
5 - .module('dialoga')  
6 - .factory('ArticleService', ArticleService);  
7 -  
8 - /** @ngInject */  
9 - function ArticleService($http, $q, $rootScope, API, UtilService, Slug, $log) {  
10 - $log.debug('ArticleService');  
11 -  
12 - var idArticleHome = API.articleId.home;  
13 - var idArticleAbout = API.articleId.about;  
14 - var idArticleTerms = API.articleId.terms;  
15 -  
16 - var _savedAbstract = null;  
17 -  
18 - var service = {  
19 - apiArticles: $rootScope.basePath + '/api/v1/articles/',  
20 - getHome: getHome,  
21 - getAbout: getAbout,  
22 - getTerms: getTerms,  
23 - getArticleById: getArticleById,  
24 - getArticleBySlug: getArticleBySlug,  
25 - getCategories: getCategories,  
26 - getCategoryBySlug: getCategoryBySlug,  
27 - getPrograms: getPrograms,  
28 - getContentById: getContentById,  
29 - setHomeAbstract: setHomeAbstract,  
30 - getHomeAbstract: getHomeAbstract  
31 - };  
32 -  
33 - var CACHE = {}; // cache by article id  
34 -  
35 - return service;  
36 -  
37 - function loadArticleById (articleId, params, cbSuccess, cbError) {  
38 -  
39 - var url = service.apiArticles + articleId;  
40 - var paramsExtended = angular.extend({}, params);  
41 -  
42 - UtilService.get(url, {params: paramsExtended}).then(function(data){  
43 - CACHE[articleId] = data;  
44 - cbSuccess(data);  
45 - }, function(error){  
46 - cbError(error);  
47 - });  
48 - }  
49 -  
50 - function getArticleById (articleId, params, cbSuccess, cbError) {  
51 - var cachedArticle = CACHE[articleId];  
52 -  
53 - if(cachedArticle){  
54 - cbSuccess(cachedArticle);  
55 - }else{  
56 - loadArticleById(articleId, params, cbSuccess, cbError);  
57 - }  
58 - }  
59 -  
60 - function getArticleBySlug (slug, cbSuccess, cbError) {  
61 - var vm = this;  
62 -  
63 - /**  
64 - * XXX: get from home article util we have a endpoint to do-it.  
65 - */  
66 - vm.getHome(function (data) {  
67 - var mainArticle = data.article;  
68 - var programList = mainArticle.children;  
69 - var categories = mainArticle.categories;  
70 -  
71 - $rootScope._CATEGORIES = $rootScope._CATEGORIES ? $rootScope._CATEGORIES : categories;  
72 -  
73 - var result = null;  
74 - for (var i = programList.length - 1; i >= 0; i--) {  
75 - var program = programList[i];  
76 -  
77 - if(!program.slug){  
78 - program.slug = Slug.slugify(program.title);  
79 - }  
80 -  
81 - if(program.slug === slug){  
82 - result = program;  
83 - break;  
84 - }  
85 - }  
86 -  
87 - if(result){  
88 - cbSuccess(result);  
89 - }else{  
90 - cbError('None program with slug "' + slug + '"" was found.');  
91 - }  
92 - }, cbError);  
93 - }  
94 -  
95 - function getCategories (cbSuccess, cbError) {  
96 - return getHome(function(data){  
97 - cbSuccess(data.article.categories);  
98 - }, cbError);  
99 - }  
100 -  
101 - function getCategoryBySlug (slug, cbSuccess, cbError) {  
102 - return getHome(function (data){  
103 - var result = null;  
104 -  
105 - for (var i = data.article.categories.length - 1; i >= 0; i--) {  
106 - var category = data.article.categories[i];  
107 - if (category.slug === slug) {  
108 - result = category;  
109 - break;  
110 - }  
111 - }  
112 -  
113 - cbSuccess(result);  
114 - }, cbError);  
115 - }  
116 -  
117 - function getPrograms (cbSuccess, cbError) {  
118 - return getHome(function(data){  
119 - cbSuccess(data.article.children);  
120 - }, cbError);  
121 - }  
122 -  
123 - function getContentById (contentId, cbSuccess, cbError) {  
124 - return getArticleById(contentId, {  
125 - fields: 'id,body&content_type=ProposalsDiscussionPlugin::Topic'  
126 - }, cbSuccess, cbError);  
127 - }  
128 -  
129 - function getHome (cbSuccess, cbError) {  
130 - return getArticleById(idArticleHome, {  
131 - fields: 'id,children,categories,abstract,title,image,url,setting,position',  
132 - private_token: 'null'  
133 - }, _handleCategory(cbSuccess), cbError);  
134 - }  
135 -  
136 - function getAbout (cbSuccess, cbError) {  
137 - return getArticleById(idArticleAbout, {}, cbSuccess, cbError);  
138 - }  
139 -  
140 - function getTerms (cbSuccess, cbError) {  
141 - return getArticleById(idArticleTerms, {}, cbSuccess, cbError);  
142 - }  
143 -  
144 - function _handleCategory (cbSuccess) {  
145 - // var darkFactor = 0.15;  
146 -  
147 - return function (data) {  
148 - if(data.article.categories){  
149 - // var categories = data.article.categories;  
150 -  
151 - // Handle Category Data  
152 -  
153 - // Handle Category Colors  
154 - // for (var i = categories.length - 1; i >= 0; i--) {  
155 - // var category = categories[i];  
156 - // if(category.color && !category.bgColor){  
157 - // category.colorDarker = $window.ColorLuminance(category.color, 0.15);  
158 - // }  
159 - // };  
160 - }  
161 - cbSuccess(data);  
162 - };  
163 - }  
164 -  
165 - function setHomeAbstract (newAbstract) {  
166 - _savedAbstract = newAbstract;  
167 - }  
168 -  
169 - function getHomeAbstract () {  
170 - return _savedAbstract;  
171 - }  
172 - }  
173 -})();  
src/app/pages/article/article.service.spec.js
@@ -1,67 +0,0 @@ @@ -1,67 +0,0 @@
1 -(function() {  
2 - 'use strict';  
3 -  
4 - describe('article services', function() {  
5 - var ArticleService, httpBackend;  
6 -  
7 - beforeEach(module('dialoga'));  
8 -  
9 - beforeEach(inject(function(_ArticleService_, $httpBackend) {  
10 - ArticleService = _ArticleService_;  
11 - httpBackend = $httpBackend;  
12 - }));  
13 -  
14 - it('should return the main article', function() {  
15 - var url = 'http://login.dialoga.gov.br/api/v1/articles/103358?fields=id,children,categories,abstract,title,image,url,setting,position&private_token=null';  
16 - httpBackend.whenGET(url).respond({  
17 - 'article':{'id':103358,'abstract':'\u003Cp style=\"text-align: center;\"\u003E\u003Ciframe src=\"https://www.youtube.com/embed/kpAdrO-emV0?rel=0\u0026amp;showinfo=0\u0026amp;iv_load_policy=3\u0026amp;controls=1\" style=\"max-width: 1000px; left: 5%;\" width=\"275\" height=\"200\"\u003E\u003C/iframe\u003E\u003C/p\u003E','title':'Dialoga Brasil','categories':[{'name':'Sa\u00fade','id':180,'slug':'saude','image':null},{'name':'Seguran\u00e7a P\u00fablica','id':182,'slug':'seguranca-publica','image':null},{'name':'Educa\u00e7\u00e3o','id':181,'slug':'educacao','image':null},{'name':'Redu\u00e7\u00e3o da Pobreza','id':183,'slug':'reducao-da-pobreza','image':null}],'image':null,'setting':{'custom_body_label':'Corpo','phase':'proposals','allow_topics':true,'moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Leandro Nunes dos Santos','moderate_proposals':true,'allow_members_to_edit':false},'position':null,'children':[{'id':103644,'abstract':'\u003Cp\u003EUm caminho de oportunidades com o Enem: Sisu, Prouni, Fies, Ci\u00eancia sem Fronteiras\u003C/p\u003E','title':'Ensino Superior','categories':[{'name':'Educa\u00e7\u00e3o','id':181,'slug':'educacao','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0128/enem.jpg'},'setting':{'color':'#cfe2f3','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':9},{'id':103673,'abstract':'\u003Cp\u003EA melhor escolha \u00e9 se informar.\u003C/p\u003E','title':'Incentivo ao Parto Normal','categories':[{'name':'Sa\u00fade','id':180,'slug':'saude','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0092/parto-normal.jpg'},'setting':{'color':'#ff0000','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':6},{'id':103397,'abstract':'\u003Cp\u003ERenda, inclus\u00e3o produtiva e acesso a servi\u00e7os.\u003C/p\u003E','title':'Brasil Sem Mis\u00e9ria','categories':[{'name':'Redu\u00e7\u00e3o da Pobreza','id':183,'slug':'reducao-da-pobreza','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0116/bsm_redim.jpg'},'setting':{'color':'','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':18},{'id':103379,'abstract':'\u003Cp\u003EResgate e atendimento 24 horas, sete dias da semana.\u003C/p\u003E','title':'SAMU 192 e UPAs','categories':[{'name':'Sa\u00fade','id':180,'slug':'saude','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0060/SAMU.jpg'},'setting':{'color':'#45818e','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':4},{'id':103521,'abstract':'\u003Cp\u003EMais atendimento nos munic\u00edpios, mais sa\u00fade para quem mais precisa.\u003C/p\u003E','title':'Mais M\u00e9dicos','categories':[{'name':'Sa\u00fade','id':180,'slug':'saude','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0025/Mais_M_dicos.jpg'},'setting':{'color':'#ffe599','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':1},{'id':103390,'abstract':'\u003Cp\u003EPreven\u00e7\u00e3o, tratamento e enfrentamento ao tr\u00e1fico.\u003C/p\u003E','title':'Crack, \u00e9 poss\u00edvel vencer!','categories':[{'name':'Seguran\u00e7a P\u00fablica','id':182,'slug':'seguranca-publica','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0104/crack.jpg'},'setting':{'color':'#00ff00','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':14},{'id':103592,'abstract':'\u003Cp\u003EGarantir acesso \u00e0 prote\u00e7\u00e3o social.\u003C/p\u003E','title':'Assist\u00eancia Social','categories':[{'name':'Redu\u00e7\u00e3o da Pobreza','id':183,'slug':'reducao-da-pobreza','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0122/assistencia_social.jpg'},'setting':{'color':'#a61c00','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':19},{'id':103426,'abstract':'\u003Cp\u003EDa sa\u00fade se cuida todos os dias.\u003C/p\u003E','title':'Vida saud\u00e1vel','categories':[{'name':'Sa\u00fade','id':180,'slug':'saude','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0046/vida_saudavel.jpg'},'setting':{'color':'#d9d2e9','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':7},{'id':103695,'abstract':'\u003Cp\u003ENovo modelo de atua\u00e7\u00e3o em Seguran\u00e7a P\u00fablica.\u003C/p\u003E','title':'Seguran\u00e7a P\u00fablica Integrada','categories':[{'name':'Seguran\u00e7a P\u00fablica','id':182,'slug':'seguranca-publica','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0152/policiaintegrada.jpg'},'setting':{'color':'#ff00ff','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':13},{'id':103663,'abstract':'\u003Cp\u003EMais educa\u00e7\u00e3o profissional e tecnol\u00f3gica, mais desenvolvimento\u003C/p\u003E','title':'Ensino T\u00e9cnico','categories':[{'name':'Educa\u00e7\u00e3o','id':181,'slug':'educacao','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0134/Ensino_tecnico.jpg'},'setting':{'color':'#d0e0e3','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':10},{'id':103472,'abstract':'\u003Cp\u003EPol\u00edcia Federal, Pol\u00edcia Rodovi\u00e1ria Federal e For\u00e7a Nacional de Seguran\u00e7a P\u00fablica.\u003C/p\u003E','title':'For\u00e7as Federais de Seguran\u00e7a','categories':[{'name':'Seguran\u00e7a P\u00fablica','id':182,'slug':'seguranca-publica','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0031/federais2.png'},'setting':{'color':'','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':16},{'id':103612,'abstract':'\u003Cp\u003EGarantir \u00e1gua para beber e produzir.\u003C/p\u003E','title':'Cisternas','categories':[{'name':'Redu\u00e7\u00e3o da Pobreza','id':183,'slug':'reducao-da-pobreza','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0039/cisterna_redim.jpg'},'setting':{'color':'#0000ff','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':20},{'id':103442,'abstract':'\u003Cp\u003EComplemento \u00e0 renda e acompanhamento em educa\u00e7\u00e3o e sa\u00fade.\u003C/p\u003E','title':'Bolsa Fam\u00edlia','categories':[{'name':'Redu\u00e7\u00e3o da Pobreza','id':183,'slug':'reducao-da-pobreza','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0013/bolsa_familia_redim.jpg'},'setting':{'color':'#ff9900','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':17},{'id':103507,'abstract':'\u003Cp\u003ETecnologia a servi\u00e7o da seguran\u00e7a do cidad\u00e3o.\u003C/p\u003E','title':'Sinesp','categories':[{'name':'Seguran\u00e7a P\u00fablica','id':182,'slug':'seguranca-publica','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0098/sinesp.png'},'setting':{'color':'#00ff00','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':12},{'id':103683,'abstract':'\u003Cp\u003ESa\u00fade n\u00e3o tem pre\u00e7o.\u003C/p\u003E','title':'Aqui tem Farm\u00e1cia Popular','categories':[{'name':'Sa\u00fade','id':180,'slug':'saude','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0019/saude_nao_tem_preco.jpg'},'setting':{'color':'#e69138','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':5},{'id':103457,'abstract':'\u003Cp\u003EA\u00e7\u00e3o conjunta e coopera\u00e7\u00e3o transfronteiri\u00e7a.\u003C/p\u003E','title':'Prote\u00e7\u00e3o das Fronteiras','categories':[{'name':'Seguran\u00e7a P\u00fablica','id':182,'slug':'seguranca-publica','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0110/fronteira_redim.jpg'},'setting':{'color':'#a64d79','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':15},{'id':103494,'abstract':'\u003Cp\u003EDa Educa\u00e7\u00e3o Infantil ao Ensino M\u00e9dio.\u003C/p\u003E','title':'Educa\u00e7\u00e3o B\u00e1sica','categories':[{'name':'Educa\u00e7\u00e3o','id':181,'slug':'educacao','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0076/Educa__o_B_sica.jpg'},'setting':{'color':'#fce5cd','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':8},{'id':103359,'abstract':'\u003Cp\u003EAcesso a exames e consultas com especialistas.\u003C/p\u003E','title':'Mais Especialidades','categories':[{'name':'Sa\u00fade','id':180,'slug':'saude','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0083/mais_especialidades1.png'},'setting':{'color':'#ea9999','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':2},{'id':103485,'abstract':'\u003Cp\u003ECaminho para uma educa\u00e7\u00e3o de qualidade.\u003C/p\u003E','title':'Valoriza\u00e7\u00e3o dos Professores','categories':[{'name':'Educa\u00e7\u00e3o','id':181,'slug':'educacao','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0140/valorizacao_professor.jpg'},'setting':{'color':'#ffff00','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':11},{'id':103416,'abstract':'\u003Cp\u003EEstrutura adequada para atender melhor a popula\u00e7\u00e3o na aten\u00e7\u00e3o b\u00e1sica.\u003C/p\u003E','title':'Melhorar os Postos de Sa\u00fade','categories':[{'name':'Sa\u00fade','id':180,'slug':'saude','image':null}],'image':{'url':'/image_uploads/dialoga/0000/0053/requalif_redim.jpg'},'setting':{'color':'#cc4125','moderate_comments':false,'comment_paragraph_plugin_activate':false,'author_name':'Ronald Emerson Scherolt da Costa','allow_members_to_edit':false},'position':3}]}});  
18 -  
19 - ArticleService.getHome(function(result){  
20 - expect(result.article).toBeDefined();  
21 - expect(result.article.title).toEqual('Dialoga Brasil');  
22 - expect(result.article.categories).toBeDefined();  
23 - });  
24 -  
25 - httpBackend.flush();  
26 - });  
27 -  
28 - // it('should return a list of articles', function() {  
29 -  
30 - // httpBackend.whenGET('http://login.dialoga.gov.br/api/v1/articles').respond({  
31 - // "articles": [  
32 - // {  
33 - // abstract: "Que exista educação continuada permanente dos profissionais!!",  
34 - // author: null,  
35 - // body: "",  
36 - // categories: [],  
37 - // children: [],  
38 - // created_at: "2015/08/04 16:36:13",  
39 - // end_date: null,  
40 - // hits: 0,  
41 - // id: 120568,  
42 - // image: null,  
43 - // parent: {id: 103379,…},  
44 - // position: null,  
45 - // profile: {identifier: "dialoga", name: "dialoga", id: 19195, created_at: "2015/04/15 09:38:36", image: null},  
46 - // setting: {comment_paragraph_plugin_activate: false, author_name: "estacio"},  
47 - // start_date: null,  
48 - // tag_list: [],  
49 - // title: "article_f4f4601c-0f36-e90e-d01a-9871f0bd126b",  
50 - // votes_against: 0,  
51 - // votes_for: 0,  
52 - // }  
53 - // ]  
54 - // });  
55 -  
56 - // ArticleService.getList().then(function(result) {  
57 - // console.log('result', result);  
58 -  
59 - // expect(result.data.article).toBeDefined();  
60 - // expect(result.data.article.title).toEqual('Dialoga Brasil');  
61 -  
62 - // });  
63 -  
64 - // httpBackend.flush();  
65 - // });  
66 - });  
67 -})();  
src/app/pages/duvidas/duvidas.controller.js
@@ -6,16 +6,12 @@ @@ -6,16 +6,12 @@
6 .controller('DuvidasPageController', DuvidasPageController); 6 .controller('DuvidasPageController', DuvidasPageController);
7 7
8 /** @ngInject */ 8 /** @ngInject */
9 - function DuvidasPageController(ArticleService, $state, $location, $scope, $rootScope, $log) { 9 + function DuvidasPageController(DialogaService, $log) {
10 $log.debug('DuvidasPageController'); 10 $log.debug('DuvidasPageController');
11 11
12 var vm = this; 12 var vm = this;
13 13
14 - vm.ArticleService = ArticleService;  
15 - vm.$state = $state;  
16 - vm.$location = $location;  
17 - vm.$scope = $scope;  
18 - vm.$rootScope = $rootScope; 14 + vm.DialogaService = DialogaService;
19 vm.$log = $log; 15 vm.$log = $log;
20 16
21 vm.init(); 17 vm.init();
@@ -24,12 +20,8 @@ @@ -24,12 +20,8 @@
24 DuvidasPageController.prototype.init = function () { 20 DuvidasPageController.prototype.init = function () {
25 var vm = this; 21 var vm = this;
26 22
27 - var params = vm.$state.params;  
28 - var slug = params.slug; 23 + vm.questions = null;
29 24
30 - vm.article = null;  
31 - vm.categories = null;  
32 - vm.currentCategory = null;  
33 vm.loading = true; 25 vm.loading = true;
34 vm.error = false; 26 vm.error = false;
35 27
@@ -40,12 +32,11 @@ @@ -40,12 +32,11 @@
40 DuvidasPageController.prototype.loadData = function () { 32 DuvidasPageController.prototype.loadData = function () {
41 var vm = this; 33 var vm = this;
42 34
43 - vm.ArticleService.getCategories(function(categories){  
44 - vm.categories = categories; 35 + vm.DialogaService.getQuestions(function(questions){
  36 + vm.questions = questions;
45 }, function (error) { 37 }, function (error) {
46 vm.error = error; 38 vm.error = error;
47 vm.$log.error(error); 39 vm.$log.error(error);
48 }); 40 });
49 -  
50 }; 41 };
51 })(); 42 })();
src/app/pages/erro/erro.html 0 → 100644
@@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
  1 +<div class="page--erro">
  2 + <div class="container">
  3 + <div class="row">
  4 + <div class="row-height">
  5 + <div class="col-sm-4 col-sm-height col-middle">
  6 + <div class="inside inside-full-height">
  7 + <div class="content">
  8 + <span class="icon-circle icon-wrapper-rounded">
  9 + <span class="glyphicon glyphicon-remove" aria-hidden></span>
  10 + </span>
  11 + <h1>Erro</h1>
  12 + <p>
  13 + <span style="font-weight:bold;">Mas você ainda pode:</span>
  14 + <br>
  15 + <!-- <button type="button" class="btn btn-link" ng-click="goBack()">retornar à página anterior</button> -->
  16 + <!-- <span>&#8226;</span> -->
  17 + <button type="button" class="btn btn-link" ui-sref="inicio">retornar à página inicial</button>
  18 + </p>
  19 + </div>
  20 + </div>
  21 + </div>
  22 + </div>
  23 + </div>
  24 + </div>
  25 +</div>
src/app/pages/erro/erro.scss 0 → 100644
@@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
  1 +.page--erro {
  2 + background-color: #f9f9f9;
  3 +
  4 + h1 {
  5 + color: #464646;
  6 + font-size: 72px;
  7 + font-weight: bold;
  8 + margin-bottom: 40px;
  9 + }
  10 +
  11 + .row-height {
  12 + min-height: 400px;
  13 + }
  14 +
  15 + .content {
  16 + text-align: center;
  17 + }
  18 +
  19 + .icon-circle {
  20 + display: inline-block;
  21 + font-size: 40px;
  22 + line-height: 33px;
  23 + font-weight: normal;
  24 +
  25 + position: relative;
  26 + top: -5px;
  27 + padding: 20px;
  28 + margin-top: 5px;
  29 + margin-right: 30px;
  30 +
  31 + color: #fff;
  32 + background: #c93e55;
  33 + }
  34 +
  35 + h1 {
  36 + display: inline-block;
  37 + }
  38 +}
src/app/pages/footer/footer.html
@@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
3 <div class="row"> 3 <div class="row">
4 <div class="col-xs-12 text-center"> 4 <div class="col-xs-12 text-center">
5 <a id="termos-de-uso" ui-sref="termos-de-uso">Termos de uso</a> 5 <a id="termos-de-uso" ui-sref="termos-de-uso">Termos de uso</a>
6 - <a href="#header" class="pull-right" ng-click="scrollTo('#header')">Voltar para o topo</a> 6 + <a href="#header" style="position:absolute;right:0;top:-10px;" ng-click="scrollTo('#header')">Voltar para o topo</a>
7 </div> 7 </div>
8 </div> 8 </div>
9 </div> 9 </div>
src/app/pages/header/header.html
@@ -12,9 +12,9 @@ @@ -12,9 +12,9 @@
12 </div> 12 </div>
13 </div> 13 </div>
14 14
15 - <div class="row"> 15 + <!-- <div class="row">
16 <div class="col-sm-12"> 16 <div class="col-sm-12">
17 <div ncy-breadcrumb></div> 17 <div ncy-breadcrumb></div>
18 </div> 18 </div>
19 - </div> 19 + </div> -->
20 </header> 20 </header>
src/app/pages/inicio/inicio.controller.js
@@ -7,11 +7,12 @@ @@ -7,11 +7,12 @@
7 .controller('InicioPageController', InicioPageController); 7 .controller('InicioPageController', InicioPageController);
8 8
9 /** @ngInject */ 9 /** @ngInject */
10 - function InicioPageController(ArticleService, $rootScope, $sce, $log) { 10 + function InicioPageController(DialogaService, $scope, $sce, $log) {
11 var vm = this; 11 var vm = this;
12 12
13 // aliases 13 // aliases
14 - vm.ArticleService = ArticleService; 14 + vm.DialogaService = DialogaService;
  15 + vm.$scope = $scope;
15 vm.$sce = $sce; 16 vm.$sce = $sce;
16 vm.$log = $log; 17 vm.$log = $log;
17 18
@@ -22,56 +23,95 @@ @@ -22,56 +23,95 @@
22 InicioPageController.prototype.init = function() { 23 InicioPageController.prototype.init = function() {
23 var vm = this; 24 var vm = this;
24 25
  26 + vm.article = null;
  27 + vm.themes = null;
  28 + vm.selectedTheme = null;
  29 + vm.programs = null;
  30 + vm.filtredPrograms = null;
  31 + vm.query = null;
  32 +
25 vm.error = null; 33 vm.error = null;
26 - vm.loading = true;  
27 - vm.loadHomeArticle(); 34 +
  35 + vm.loadData();
  36 + vm.attachListeners();
28 }; 37 };
29 38
30 - InicioPageController.prototype.loadHomeArticle = function() { 39 + InicioPageController.prototype.loadData = function() {
31 var vm = this; 40 var vm = this;
32 41
33 - vm.content = vm.ArticleService.getHomeAbstract();  
34 - vm.isCached = !!vm.content; 42 + vm.loading = true;
  43 + vm.loadingEvents = true;
  44 + vm.loadingThemes = true;
  45 + vm.loadingPrograms = true;
35 46
36 - if (vm.isCached) {  
37 - hideBackground(2000);  
38 - } 47 + // Load main content
  48 + vm.DialogaService.getHome(function(data) {
  49 + vm.article = data.article;
  50 +
  51 + if (vm.article.videoIsLoaded) {
  52 + hideBackground(2000);
  53 + }
39 54
40 - vm.ArticleService.getHome(function(data) { 55 + loadAfterHome();
  56 +
41 vm.loading = false; 57 vm.loading = false;
42 - vm.article = data.article;  
43 }, function(error) { 58 }, function(error) {
44 - vm.$log.error('Error on getHome article.', error);  
45 - vm.error = 'Erro ao carregar o conteúdo principal.'; 59 + vm.$log.error('Error on getHome.', error);
46 }); 60 });
  61 +
  62 + function loadAfterHome () {
  63 + // Load event list
  64 + // vm.DialogaService.getEvents(function(data) {
  65 + // vm.events = data;
  66 + // vm.loadingEvents = false;
  67 + // }, function(error) {
  68 + // vm.$log.error('Error on getEvents.', error);
  69 + // });
  70 +
  71 + // Load theme list
  72 + vm.DialogaService.getThemes(function(data) {
  73 + vm.themes = data;
  74 + vm.loadingThemes = false;
  75 + }, function(error) {
  76 + vm.$log.error('Error on getThemes.', error);
  77 + });
  78 +
  79 + // Load program list
  80 + vm.DialogaService.getProgramsRandom(function(data) {
  81 + vm.programs = vm.article.children;
  82 + vm.filtredPrograms = data;
  83 + vm.loadingPrograms = false;
  84 + }, function(error) {
  85 + vm.$log.error('Error on getPrograms.', error);
  86 + });
  87 + }
  88 +
47 }; 89 };
48 90
49 InicioPageController.prototype.showVideo = function() { 91 InicioPageController.prototype.showVideo = function() {
50 var vm = this; 92 var vm = this;
51 93
52 // we need handle home content 94 // we need handle home content
53 - if (vm.isCached) { 95 + if (vm.article.videoIsLoaded) {
54 hideBackground(0); // force to hide 96 hideBackground(0); // force to hide
55 - vm.$log.warn('The content already cached. Aborting.'); 97 + vm.$log.debug('The content already cached. Show-it!');
56 return; 98 return;
57 } 99 }
58 100
59 - vm.content = vm.handleHomeAbstract(vm.article.abstract);  
60 - vm.ArticleService.setHomeAbstract(vm.content);  
61 -  
62 // inject dependencies 101 // inject dependencies
63 injectIframeApiJs(); 102 injectIframeApiJs();
64 window.onYouTubeIframeAPIReady = window.onYouTubeIframeAPIReady || onYouTubeIframeAPIReady; 103 window.onYouTubeIframeAPIReady = window.onYouTubeIframeAPIReady || onYouTubeIframeAPIReady;
65 window.onYouTubePlayerReady = window.onYouTubePlayerReady || onYouTubePlayerReady; 104 window.onYouTubePlayerReady = window.onYouTubePlayerReady || onYouTubePlayerReady;
  105 +
  106 + vm.article.videoIsLoaded = true;
66 }; 107 };
67 108
68 - InicioPageController.prototype.handleHomeAbstract = function(abstract) { 109 + InicioPageController.prototype.attachListeners = function() {
69 var vm = this; 110 var vm = this;
70 111
71 - abstract = forceIframeParams(abstract);  
72 - abstract = removeStylefromIframe(abstract);  
73 -  
74 - return vm.$sce.trustAsHtml(abstract); 112 + vm.$scope.$on('change-selectedCategory', function (selectedCategory) {
  113 + vm.selectedTheme = selectedCategory;
  114 + });
75 }; 115 };
76 116
77 function injectIframeApiJs() { 117 function injectIframeApiJs() {
@@ -102,51 +142,4 @@ @@ -102,51 +142,4 @@
102 angular.element($elBg).fadeOut(ms || 100); 142 angular.element($elBg).fadeOut(ms || 100);
103 // angular.element($elBg).hide(); 143 // angular.element($elBg).hide();
104 } 144 }
105 -  
106 - function forceIframeParams(abstract) {  
107 - var patternIframe = '<iframe src="';  
108 - var indexOfIframe = abstract.indexOf(patternIframe);  
109 -  
110 - if (indexOfIframe === -1) {  
111 - return abstract;  
112 - }  
113 -  
114 - var startSrcUrl = indexOfIframe + patternIframe.length;  
115 - var endSrcUrl = abstract.indexOf('"', startSrcUrl);  
116 - var srcUrl = abstract.substring(startSrcUrl , endSrcUrl);  
117 - var resultUrl = srcUrl;  
118 - var c = (srcUrl.indexOf('?') !== -1) ? '&' : ''; // already have url params. So, append-it  
119 -  
120 - // enable js api  
121 - if (srcUrl.indexOf('enablejsapi=1') === -1) {  
122 - resultUrl += c + 'enablejsapi=1';  
123 - c = '&'; // force to always use '&' after here  
124 - }  
125 -  
126 - // set opaque mode  
127 - if (srcUrl.indexOf('wmode=opaque') === -1) {  
128 - resultUrl += c + 'wmode=opaque';  
129 - // c = '&'; // force to always use '&' after here  
130 - }  
131 -  
132 - abstract = abstract.replace(srcUrl, resultUrl);  
133 -  
134 - return abstract;  
135 - }  
136 -  
137 - function removeStylefromIframe (abstract) {  
138 - var patternIframe = 'style="';  
139 - var indexOfIframe = abstract.indexOf('<iframe');  
140 - var indexOfStyleOnIframe = abstract.indexOf('style="', indexOfIframe);  
141 -  
142 - if (indexOfStyleOnIframe === -1) {  
143 - return abstract;  
144 - }  
145 -  
146 - var startStyleContent = indexOfStyleOnIframe + patternIframe.length;  
147 - var endStyleContent = abstract.indexOf('"', startStyleContent);  
148 - var style = abstract.substring(startStyleContent , endStyleContent);  
149 -  
150 - return abstract.replace(style, '');  
151 - }  
152 })(); 145 })();
src/app/pages/inicio/inicio.html
1 -<section class="container" role="main">  
2 - <div class="row">  
3 - <div class="col-sm-10 col-sm-offset-1">  
4 - <div class="video-wrapper">  
5 - <div class="video-player js-youtube">  
6 - <div class="embed-responsive embed-responsive-16by9">  
7 - <div class="js-iframe" ng-show="pageInicio.content" ng-bind-html="pageInicio.content"></div>  
8 - <div class="video-background" ng-click="pageInicio.showVideo()">  
9 - <div class="video-thumbnail" aria-hidden="true" style="background-image:url(/assets/images/youtube-background.png)"></div>  
10 - <button class="video-play-button" aria-live="assertive" aria-label="Assistir o vídeo tutorial Dialoga Brasil">  
11 - <svg height="100%" version="1.1" viewBox="0 0 68 48" width="100%"><path class="ytp-play-button-bg" d="m .66,37.62 c 0,0 .66,4.70 2.70,6.77 2.58,2.71 5.98,2.63 7.49,2.91 5.43,.52 23.10,.68 23.12,.68 .00,-1.3e-5 14.29,-0.02 23.81,-0.71 1.32,-0.15 4.22,-0.17 6.81,-2.89 2.03,-2.07 2.70,-6.77 2.70,-6.77 0,0 .67,-5.52 .67,-11.04 l 0,-5.17 c 0,-5.52 -0.67,-11.04 -0.67,-11.04 0,0 -0.66,-4.70 -2.70,-6.77 C 62.03,.86 59.13,.84 57.80,.69 48.28,0 34.00,0 34.00,0 33.97,0 19.69,0 10.18,.69 8.85,.84 5.95,.86 3.36,3.58 1.32,5.65 .66,10.35 .66,10.35 c 0,0 -0.55,4.50 -0.66,9.45 l 0,8.36 c .10,4.94 .66,9.45 .66,9.45 z" fill="#1f1f1e" fill-opacity="0.9"></path><path d="m 26.96,13.67 18.37,9.62 -18.37,9.55 -0.00,-19.17 z" fill="#fff"></path><path d="M 45.02,23.46 45.32,23.28 26.96,13.67 43.32,24.34 45.02,23.46 z" fill="#ccc"></path></svg>  
12 - </button> 1 +<div class="page--inicio">
  2 + <section class="section-video" role="main">
  3 + <div class="container">
  4 + <div class="row">
  5 + <div class="col-sm-10 col-sm-offset-1">
  6 + <div class="video-wrapper">
  7 + <div class="video-player js-youtube">
  8 + <div class="embed-responsive embed-responsive-16by9">
  9 + <div class="js-iframe" ng-if="pageInicio.article.videoIsLoaded" ng-bind-html="pageInicio.article.abstractTrusted"></div>
  10 + <div class="video-background" ng-click="pageInicio.showVideo()">
  11 + <div class="video-thumbnail" aria-hidden="true" style="background-image:url(/assets/images/youtube-background.png)"></div>
  12 + <button class="video-play-button" aria-live="assertive" aria-label="Assistir o vídeo tutorial Dialoga Brasil">
  13 + <svg height="100%" version="1.1" viewbox="0 0 68 48" width="100%"><path class="ytp-play-button-bg" d="m .66,37.62 c 0,0 .66,4.70 2.70,6.77 2.58,2.71 5.98,2.63 7.49,2.91 5.43,.52 23.10,.68 23.12,.68 .00,-1.3e-5 14.29,-0.02 23.81,-0.71 1.32,-0.15 4.22,-0.17 6.81,-2.89 2.03,-2.07 2.70,-6.77 2.70,-6.77 0,0 .67,-5.52 .67,-11.04 l 0,-5.17 c 0,-5.52 -0.67,-11.04 -0.67,-11.04 0,0 -0.66,-4.70 -2.70,-6.77 C 62.03,.86 59.13,.84 57.80,.69 48.28,0 34.00,0 34.00,0 33.97,0 19.69,0 10.18,.69 8.85,.84 5.95,.86 3.36,3.58 1.32,5.65 .66,10.35 .66,10.35 c 0,0 -0.55,4.50 -0.66,9.45 l 0,8.36 c .10,4.94 .66,9.45 .66,9.45 z" fill="#1f1f1e" fill-opacity="0.9"></path><path d="m 26.96,13.67 18.37,9.62 -18.37,9.55 -0.00,-19.17 z" fill="#fff"></path><path d="M 45.02,23.46 45.32,23.28 26.96,13.67 43.32,24.34 45.02,23.46 z" fill="#ccc"></path></svg>
  14 + </button>
  15 + </div>
  16 + </div>
13 </div> 17 </div>
14 </div> 18 </div>
15 </div> 19 </div>
16 </div> 20 </div>
17 </div> 21 </div>
18 - </div>  
19 - <!-- <div class="js-event-wrapper hide" ng-show="inicio.eventListIsVisible"> -->  
20 - <div class="js-event-wrapper">  
21 - <event-list></event-list>  
22 - </div>  
23 -</section> 22 + </section>
24 23
25 -<section class="info-section" ng-if="pageInicio.loading || pageInicio.error">  
26 - <div class="container">  
27 - <div class="col-md-12">  
28 - <div ng-if="pageInicio.loading && !pageInicio.error">  
29 - <div class="alert alert-info">Carregando conteúdo...</div> 24 + <section class="section-event">
  25 + <div ng-if="pageInicio.events">
  26 + <event-list events="[]"></event-list>
  27 + </div>
  28 + <div ng-if="!pageInicio.events && pageInicio.loadingEvents" class="container">
  29 + <div class="row">
  30 + <div class="col-sm-12">
  31 + <div class="alert alert-info" role="alert">Carregando lista de eventos.</div>
30 </div> 32 </div>
31 -  
32 - <div ng-if="pageInicio.error">  
33 - <div class="alert alert-danger">{{pageInicio.error}}</div> 33 + </div>
  34 + </div>
  35 + <div ng-if="!pageInicio.events && pageInicio.eventsError" class="container">
  36 + <div class="row">
  37 + <div class="col-sm-12">
  38 + <div class="alert alert-danger" role="alert">Não foi possível carregar a lista de eventos neste momento.</div>
34 </div> 39 </div>
35 </div> 40 </div>
36 </div> 41 </div>
37 -</section> 42 + </section>
38 43
39 -<section class="section-gray section-space-up" ng-if="pageInicio.article">  
40 - <div class="container">  
41 - <div id="lista-de-programas" class="row">  
42 - <div class="col-sm-4 col-md-3">  
43 - <category-list></category-list> 44 + <section class="section-info" ng-if="pageInicio.loading || pageInicio.error">
  45 + <div class="container">
  46 + <div class="row">
  47 + <div class="col-md-12">
  48 + <div ng-if="pageInicio.loading && !pageInicio.error">
  49 + <div class="alert alert-info" role="alert">Carregando conteúdo...</div>
  50 + </div>
  51 +
  52 + <div ng-if="pageInicio.error">
  53 + <div class="alert alert-danger" role="alert">
  54 + Erro ao carregar o conteúdo principal.
  55 + </div>
  56 + </div>
  57 + </div>
  58 + </div>
44 </div> 59 </div>
45 - <div class="col-sm-8 col-md-9">  
46 - <article-grid></article-grid> 60 + </section>
  61 +
  62 + <section class="section--articles section-gray section-space-up" ng-if="pageInicio.article">
  63 + <div class="container">
  64 + <div id="lista-de-programas" class="row">
  65 + <div class="col-sm-4 col-md-3">
  66 + <div ng-if="pageInicio.themes">
  67 + <category-list categories="pageInicio.themes" selected-category="pageInicio.selectedTheme"></category-list>
  68 + </div>
  69 + <div ng-if="!pageInicio.themes && pageInicio.loadingThemes">
  70 + <div class="alert alert-info" role="alert">
  71 + Carregando temas.
  72 + </div>
  73 + </div>
  74 + <div ng-if="!pageInicio.themes && pageInicio.themesError">
  75 + <div class="alert alert-danger" role="alert">
  76 + Não foi possível carregar a lista de temas neste momento.
  77 + </div>
  78 + </div>
  79 + </div>
  80 + <div class="col-sm-8 col-md-9">
  81 + <div class="row">
  82 + <header class="header">
  83 + <h2>Conheça os programas <span class="small">({{pageInicio.filtredPrograms.length}}/{{::pageInicio.programs.length}})</span></h2>
  84 + <button type="button" class="btn btn-link" ng-click="pageInicio.showAll($event)">
  85 + <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span> Ver todos os {{::pageInicio.programs.length}} programas
  86 + </button>
  87 + </header>
  88 + </div>
  89 + <div class="row">
  90 + <div class="col-xs-6 col-sm-7 col-md-9">
  91 + <label for="articleQueryFilter" class="control-label sr-only">Filtrar programas:</label>
  92 + <input id="articleQueryFilter" type="search" class="form-control" ng-model="pageInicio.query" placeholder="Filtrar programas" aria-label="Filtrar programas" >
  93 + </div>
  94 + </div>
  95 +
  96 + <div ng-if="pageInicio.programs">
  97 + <article-grid articles="pageInicio.filtredPrograms"></article-grid>
  98 + </div>
  99 + <div ng-if="!pageInicio.programs && pageInicio.loadingPrograms">
  100 + <div class="alert alert-info" role="alert">
  101 + Carregando programas.
  102 + </div>
  103 + </div>
  104 + <div ng-if="!pageInicio.programs && pageInicio.programsError">
  105 + <div class="alert alert-danger" role="alert">
  106 + Não foi possível carregar a lista de programas neste momento.
  107 + </div>
  108 + </div>
  109 + </div>
47 </div> 110 </div>
48 </div> 111 </div>
49 - </div>  
50 -</section> 112 + </section>
  113 +</div>
src/app/pages/inicio/inicio.scss
  1 +.page--inicio {
  2 + margin-top: 20px;
  3 +
  4 + .section--articles {
  5 +
  6 + .header {
  7 + position: relative;
  8 + height: 40px;
  9 + margin-bottom: 10px;
  10 +
  11 + button {
  12 + position: absolute;
  13 + right: 0;
  14 + top: 2px;
  15 + }
  16 + }
  17 +
  18 + .form-inline {
  19 + input,
  20 + select {
  21 + width: 100%;
  22 + }
  23 + }
  24 + }
  25 +}
  26 +
1 .section-gray { 27 .section-gray {
2 background-color: $gray; 28 background-color: $gray;
3 29
src/app/pages/programas/programa-content.controller.js
@@ -6,45 +6,46 @@ @@ -6,45 +6,46 @@
6 .controller('ProgramaContentPageController', ProgramaContentPageController); 6 .controller('ProgramaContentPageController', ProgramaContentPageController);
7 7
8 /** @ngInject */ 8 /** @ngInject */
9 - function ProgramaContentPageController(ArticleService, $state, $location, $scope, $rootScope, $log) { 9 + function ProgramaContentPageController(DialogaService, $state, $scope, $rootScope, $log) {
10 $log.debug('ProgramaContentPageController'); 10 $log.debug('ProgramaContentPageController');
11 11
12 var vm = this; 12 var vm = this;
13 13
14 - vm.ArticleService = ArticleService; 14 + vm.DialogaService = DialogaService;
15 vm.$state = $state; 15 vm.$state = $state;
16 - vm.$location = $location;  
17 vm.$scope = $scope; 16 vm.$scope = $scope;
18 vm.$rootScope = $rootScope; 17 vm.$rootScope = $rootScope;
19 vm.$log = $log; 18 vm.$log = $log;
20 19
21 vm.init(); 20 vm.init();
  21 + vm.loadData();
  22 + vm.attachListeners();
22 } 23 }
23 24
24 ProgramaContentPageController.prototype.init = function() { 25 ProgramaContentPageController.prototype.init = function() {
25 var vm = this; 26 var vm = this;
26 27
27 - var params = vm.$state.params;  
28 -  
29 vm.article = null; 28 vm.article = null;
30 vm.category = null; 29 vm.category = null;
31 - vm.loading = true;  
32 - vm.error = false;  
33 - vm.slug = params.slug;  
34 30
35 - vm.loadData();  
36 - vm.attachListeners(); 31 + vm.error = false;
37 }; 32 };
38 33
39 ProgramaContentPageController.prototype.loadData = function() { 34 ProgramaContentPageController.prototype.loadData = function() {
40 var vm = this; 35 var vm = this;
41 36
42 - vm.ArticleService.getArticleBySlug(vm.slug, function(article) { 37 + vm.loading = true;
  38 +
  39 + // Get program by slug
  40 + var slug = vm.$state.params.slug;
  41 + vm.DialogaService.getProgramBySlug(slug, function(article) {
43 vm.article = article; 42 vm.article = article;
44 vm.category = vm.article.categories[0]; 43 vm.category = vm.article.categories[0];
45 44
  45 + // update the breadcrumb
46 vm.$rootScope.contentTitle = vm.article.title; 46 vm.$rootScope.contentTitle = vm.article.title;
47 47
  48 + // set the banner image with full image path
48 if (!vm.banner) { 49 if (!vm.banner) {
49 vm.banner = { 50 vm.banner = {
50 src: vm.$rootScope.basePath + vm.article.image.url, 51 src: vm.$rootScope.basePath + vm.article.image.url,
@@ -52,39 +53,37 @@ @@ -52,39 +53,37 @@
52 }; 53 };
53 } 54 }
54 55
55 - vm.loadContent();  
56 - 56 + vm.DialogaService.getProposalsByTopicId(vm.article.id, {}, function(data){
  57 + vm.proposals = data.children;
  58 + vm.proposalsTopRated = [
  59 + {abstract: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec tristique consectetur neque, at tincidunt enim volutpat sit amet. Integer sed cursus metus, non luctus risus. Mauris elementum est quis vehicula ullamcorper.'},
  60 + {abstract: 'Mauris elementum est quis vehicula ullamcorper. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec tristique consectetur neque, at tincidunt enim volutpat sit amet. Integer sed cursus metus, non luctus risus.'},
  61 + {abstract: 'Integer sed cursus metus, non luctus risus. Mauris elementum est quis vehicula ullamcorper. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec tristique consectetur neque, at tincidunt enim volutpat sit amet.'},
  62 + ];
  63 + }, function (error) {
  64 + vm.$log.error(error);
  65 + });
  66 +
  67 + vm.loading = false;
57 }, function(error) { 68 }, function(error) {
58 vm.$log.error(error); 69 vm.$log.error(error);
59 - vm.$log.info('Rollback to home page.');  
60 - vm.$state.go('inicio', {}, {location: true}); 70 + vm.error = error;
  71 + vm.loading = false;
  72 +
  73 + // vm.$log.info('Rollback to home page.');
  74 + // vm.$state.go('inicio', {}, {location: true});
61 }); 75 });
  76 +
62 }; 77 };
63 78
64 ProgramaContentPageController.prototype.attachListeners = function() { 79 ProgramaContentPageController.prototype.attachListeners = function() {
65 var vm = this; 80 var vm = this;
66 81
67 - vm.$scope.$on('see-proposals', function() { 82 + vm.$scope.$on('proposal-carousel:toProposals', function() {
68 vm.$log.warn('TODO: handle see proposals / ranking'); 83 vm.$log.warn('TODO: handle see proposals / ranking');
69 }); 84 });
70 }; 85 };
71 86
72 - ProgramaContentPageController.prototype.loadContent = function() {  
73 - var vm = this;  
74 -  
75 - vm.loading = true;  
76 - if (!vm.article.body) {  
77 - vm.ArticleService.getContentById(vm.article.id, function(data) {  
78 - vm.article.body = data.article.body;  
79 - vm.loading = false;  
80 - }, function(error) {  
81 - vm.loading = false;  
82 - vm.error = error;  
83 - });  
84 - }  
85 - vm.loading = false;  
86 - };  
87 -  
88 ProgramaContentPageController.prototype.makeProposal = function() { 87 ProgramaContentPageController.prototype.makeProposal = function() {
89 var vm = this; 88 var vm = this;
90 89
src/app/pages/programas/programa.controller.js
@@ -6,16 +6,12 @@ @@ -6,16 +6,12 @@
6 .controller('ProgramasPageController', ProgramasPageController); 6 .controller('ProgramasPageController', ProgramasPageController);
7 7
8 /** @ngInject */ 8 /** @ngInject */
9 - function ProgramasPageController(ArticleService, $state, $location, $scope, $rootScope, $log) { 9 + function ProgramasPageController(DialogaService, $log) {
10 $log.debug('ProgramasPageController'); 10 $log.debug('ProgramasPageController');
11 11
12 var vm = this; 12 var vm = this;
13 13
14 - vm.ArticleService = ArticleService;  
15 - vm.$state = $state;  
16 - vm.$location = $location;  
17 - vm.$scope = $scope;  
18 - vm.$rootScope = $rootScope; 14 + vm.DialogaService = DialogaService;
19 vm.$log = $log; 15 vm.$log = $log;
20 16
21 vm.init(); 17 vm.init();
@@ -24,12 +20,10 @@ @@ -24,12 +20,10 @@
24 ProgramasPageController.prototype.init = function () { 20 ProgramasPageController.prototype.init = function () {
25 var vm = this; 21 var vm = this;
26 22
27 - var params = vm.$state.params;  
28 - var slug = params.slug;  
29 -  
30 vm.article = null; 23 vm.article = null;
31 vm.categories = null; 24 vm.categories = null;
32 vm.currentCategory = null; 25 vm.currentCategory = null;
  26 +
33 vm.loading = true; 27 vm.loading = true;
34 vm.error = false; 28 vm.error = false;
35 29
@@ -40,37 +34,11 @@ @@ -40,37 +34,11 @@
40 ProgramasPageController.prototype.loadData = function () { 34 ProgramasPageController.prototype.loadData = function () {
41 var vm = this; 35 var vm = this;
42 36
43 - vm.ArticleService.getCategories(function(categories){  
44 - vm.categories = categories; 37 + vm.DialogaService.getTemas(function(temas){
  38 + vm.categories = temas;
45 }, function (error) { 39 }, function (error) {
46 vm.error = error; 40 vm.error = error;
47 vm.$log.error(error); 41 vm.$log.error(error);
48 }); 42 });
49 -  
50 - // vm.ArticleService.getArticleBySlug(slug, function(article){  
51 - // vm.article = article;  
52 - // vm.currentCategory = vm.article.categories[0];  
53 -  
54 - // // load proposals  
55 - // // vm.ArticleService.getRandomProposal(program.id, function(proposal){  
56 - // // vm.article.proposal = proposal;  
57 - // // }, function (error){  
58 - // // vm.$log.error(error);  
59 - // // });  
60 -  
61 - // // load events  
62 - // // vm.ArticleService.getEvents(program.id, function(proposal){  
63 - // // vm.article.proposal = proposal;  
64 - // // }, function (error){  
65 - // // vm.$log.error(error);  
66 - // // });  
67 -  
68 - // }, function (error) {  
69 - // vm.error = error;  
70 - // vm.$log.error(error);  
71 - // vm.$log.info('Rollback to home page.');  
72 - // vm.$state.go('inicio', {}, {location: true});  
73 - // });  
74 -  
75 }; 43 };
76 })(); 44 })();
src/app/pages/programas/programa.html
  1 +<div class="container">
  2 + <div class="row">
  3 + <div class="col-sm-12">
  4 + <div ncy-breadcrumb></div>
  5 + </div>
  6 + </div>
  7 +</div>
  8 +
1 <div class="page--conheca-o-programa"> 9 <div class="page--conheca-o-programa">
2 <section> 10 <section>
3 <div class="container"> 11 <div class="container">
4 - <div ng-if="!pageProgramaContent.article.body">  
5 - <div ng-if="!pageProgramaContent.error" class="alert alert-info" role="alert">Carregando detalhes sobre o progama...</div>  
6 - <div ng-if="pageProgramaContent.error" class="alert alert-warning" role="alert">{{pageProgramaContent}}</div> 12 + <div class="row">
  13 + <div class="col-sm-12">
  14 + <div ng-if="!pageProgramaContent.article && pageProgramaContent.loading" class="alert alert-info" role="alert">Carregando detalhes sobre o progama...</div>
  15 + <div ng-if="!pageProgramaContent.article && pageProgramaContent.error" class="alert alert-warning" role="alert">Erro ao carregar o programa.</div>
  16 + </div>
7 </div> 17 </div>
8 </div> 18 </div>
9 </section> 19 </section>
@@ -11,56 +21,59 @@ @@ -11,56 +21,59 @@
11 <div ng-if="pageProgramaContent.article.body" ng-class="pageProgramaContent.category.slug"> 21 <div ng-if="pageProgramaContent.article.body" ng-class="pageProgramaContent.category.slug">
12 <section> 22 <section>
13 <div class="container"> 23 <div class="container">
14 - <article class="program-preview">  
15 - <div class="row">  
16 - <div class="col-md-12">  
17 - <h1 class="program-preview--title color-theme-fg">{{::pageProgramaContent.article.title}}</h1>  
18 - </div>  
19 - <div class="col-md-8">  
20 - <div class="program-preview--box contraste-box">  
21 - <div class="program-preview--banner" ng-style="{'background-image':'url( {{::pageProgramaContent.banner.src}} )'}"></div>  
22 - <div class="program-preview--box--content-wrapper">  
23 - <div class="program-preview--icon icon-wrapper-rounded color-theme-bg" ng-class="pageProgramaContent.category.slug">  
24 - <span class="icon" ng-class="'icon-tema-' + pageProgramaContent.category.slug"></span>  
25 - </div>  
26 - <div class="program-preview--abstract color-theme-fg">  
27 - <h2>{{::stripHtml(pageProgramaContent.article.abstract)}}</h2>  
28 - </div>  
29 - <div class="program-preview--abstract-details">  
30 - <p>Lorem ipsum dolor sit amet, ea veniam mucius ocurreret vix, ius ex nisl vidisse partiendo. Blandit nominavi cum ei, paulo quaestio his ei, eum minim salutandi in. Civibus albucius in quo, et eam posse facilisis. Debet suavitate sea ut, his ei feugiat fastidii eleifend. Quo ex quando maiestatis voluptatum, mel te perpetua maiestatis, sit ceteros legendos deserunt ea. Enim dolores moderatius eu pro, ad quo ignota aliquid meliore.</p>  
31 - </div>  
32 - <div class="program-preview--share">  
33 - <ul class="list-inline">  
34 - <li>Compartilhe este programa:</li>  
35 - <li><social-share class="program-preview--share-directive"></social-share></li>  
36 - </ul>  
37 - </div>  
38 - <div class="program-preview--make-proposal">  
39 - <div class="row">  
40 - <div class="col-sm-6">  
41 - <div class="button--themed">  
42 - <button type="button" class="btn btn-block" ng-click="pageProgramaContent.makeProposal()">Faça uma proposta</button> 24 + <div class="row">
  25 + <article class="program-preview">
  26 +
  27 + <div class="col-md-12">
  28 + <h1 class="program-preview--title color-theme-fg">{{::pageProgramaContent.article.title}}</h1>
  29 + </div>
  30 + <div class="col-md-8">
  31 + <div class="program-preview--box contraste-box">
  32 + <div class="program-preview--banner" ng-style="{'background-image':'url( {{::pageProgramaContent.banner.src}} )'}"></div>
  33 + <div class="program-preview--box--content-wrapper">
  34 + <div class="program-preview--icon icon-wrapper-rounded color-theme-bg" ng-class="pageProgramaContent.category.slug">
  35 + <span class="icon" ng-class="'icon-tema-' + pageProgramaContent.category.slug"></span>
  36 + </div>
  37 + <div class="program-preview--abstract color-theme-fg">
  38 + <h2>{{::stripHtml(pageProgramaContent.article.abstract)}}</h2>
  39 + </div>
  40 + <div class="program-preview--abstract-details">
  41 + <p>Lorem ipsum dolor sit amet, ea veniam mucius ocurreret vix, ius ex nisl vidisse partiendo. Blandit nominavi cum ei, paulo quaestio his ei, eum minim salutandi in. Civibus albucius in quo, et eam posse facilisis. Debet suavitate sea ut, his ei feugiat fastidii eleifend. Quo ex quando maiestatis voluptatum, mel te perpetua maiestatis, sit ceteros legendos deserunt ea. Enim dolores moderatius eu pro, ad quo ignota aliquid meliore.</p>
  42 + </div>
  43 + <div class="program-preview--share">
  44 + <ul class="list-inline">
  45 + <li>Compartilhe este programa:</li>
  46 + <li><social-share class="program-preview--share-directive"></social-share></li>
  47 + </ul>
  48 + </div>
  49 + <div class="program-preview--make-proposal">
  50 + <div class="row">
  51 + <div class="col-sm-6">
  52 + <div class="button--themed">
  53 + <button type="button" class="btn btn-block" ng-click="pageProgramaContent.makeProposal()">Faça uma proposta</button>
  54 + </div>
43 </div> 55 </div>
44 </div> 56 </div>
45 </div> 57 </div>
46 </div> 58 </div>
47 </div> 59 </div>
48 </div> 60 </div>
49 - </div>  
50 - <div class="col-md-4">  
51 - <div class="row">  
52 - <div class="col-xs-12">  
53 - <h3 class="color-theme-fg">Propostas mais votadas</h3>  
54 - <proposal-ranking limit="'3'" display="'carousel'"></proposal-ranking>  
55 - </div>  
56 - <div class="col-xs-12">  
57 - <h3 class="color-theme-fg">Propostas nesse programa</h3>  
58 - <proposal-related article="pageProgramaContent.article"></proposal-related> 61 + <div class="col-md-4">
  62 + <div class="row">
  63 + <div class="col-xs-12">
  64 + <h3 class="color-theme-fg">Propostas mais votadas</h3>
  65 + <div ng-if="pageProgramaContent.proposalsTopRated">
  66 + <proposal-carousel proposals="pageProgramaContent.proposalsTopRated"></proposal-carousel>
  67 + </div>
  68 + </div>
  69 + <div class="col-xs-12">
  70 + <h3 class="color-theme-fg">Propostas nesse programa</h3>
  71 + <proposal-related article="pageProgramaContent.article"></proposal-related>
  72 + </div>
59 </div> 73 </div>
60 </div> 74 </div>
61 - </div>  
62 - </div>  
63 - </article> 75 + </article>
  76 + </div>
64 </div> 77 </div>
65 </section> 78 </section>
66 79
@@ -69,16 +82,16 @@ @@ -69,16 +82,16 @@
69 <div class="proposal-ranking-section-header"> 82 <div class="proposal-ranking-section-header">
70 <h3 class="color-theme-fg">Resultados de propostas mais votadas</h3> 83 <h3 class="color-theme-fg">Resultados de propostas mais votadas</h3>
71 </div> 84 </div>
72 - <div class="proposal-ranking-section-table">  
73 - <proposal-ranking limit="'5'" display="'list'"></proposal-ranking> 85 + <div class="proposal-ranking-section-table" ng-if="pageProgramaContent.proposals">
  86 + <proposal-list proposals="pageProgramaContent.proposals"></proposal-list>
74 </div> 87 </div>
75 </div> 88 </div>
76 </section> 89 </section>
77 -  
78 - <article class="program-content">  
79 - <div class="row">  
80 - <section ng-bind-html="pageProgramaContent.article.body"></section>  
81 - </div>  
82 - </article> 90 +
  91 + <section class="section-content">
  92 + <article class="program-content" ng-if="pageProgramaContent.article">
  93 + <div ng-bind-html="pageProgramaContent.article.body"></div>
  94 + </article>
  95 + </section>
83 </div> 96 </div>
84 </div> 97 </div>
src/app/pages/programas/programas.html
  1 +<div class="container">
  2 + <div class="row">
  3 + <div class="col-sm-12">
  4 + <div ncy-breadcrumb></div>
  5 + </div>
  6 + </div>
  7 +</div>
  8 +
1 <div class="page--programas"> 9 <div class="page--programas">
2 <section class="section-gray section-space-up"> 10 <section class="section-gray section-space-up">
3 <div class="container"> 11 <div class="container">
src/app/pages/propostas/proposta.html
  1 +<div class="container">
  2 + <div class="row">
  3 + <div class="col-sm-12">
  4 + <div ncy-breadcrumb></div>
  5 + </div>
  6 + </div>
  7 +</div>
  8 +
1 <div class="container page--propostas"> 9 <div class="container page--propostas">
2 <h1>TODO: Home > Proposta</h1> 10 <h1>TODO: Home > Proposta</h1>
3 </div> 11 </div>
src/app/pages/propostas/propostas.controller.js
@@ -6,16 +6,12 @@ @@ -6,16 +6,12 @@
6 .controller('PropostasPageController', PropostasPageController); 6 .controller('PropostasPageController', PropostasPageController);
7 7
8 /** @ngInject */ 8 /** @ngInject */
9 - function PropostasPageController(ArticleService, $state, $location, $scope, $rootScope, $log) { 9 + function PropostasPageController(DialogaService, $log) {
10 $log.debug('PropostasPageController'); 10 $log.debug('PropostasPageController');
11 11
12 var vm = this; 12 var vm = this;
13 13
14 - vm.ArticleService = ArticleService;  
15 - vm.$state = $state;  
16 - vm.$location = $location;  
17 - vm.$scope = $scope;  
18 - vm.$rootScope = $rootScope; 14 + vm.DialogaService = DialogaService;
19 vm.$log = $log; 15 vm.$log = $log;
20 16
21 vm.init(); 17 vm.init();
@@ -24,9 +20,6 @@ @@ -24,9 +20,6 @@
24 PropostasPageController.prototype.init = function () { 20 PropostasPageController.prototype.init = function () {
25 var vm = this; 21 var vm = this;
26 22
27 - var params = vm.$state.params;  
28 - var slug = params.slug;  
29 -  
30 vm.article = null; 23 vm.article = null;
31 vm.categories = null; 24 vm.categories = null;
32 vm.currentCategory = null; 25 vm.currentCategory = null;
@@ -40,7 +33,7 @@ @@ -40,7 +33,7 @@
40 PropostasPageController.prototype.loadData = function () { 33 PropostasPageController.prototype.loadData = function () {
41 var vm = this; 34 var vm = this;
42 35
43 - vm.ArticleService.getCategories(function(categories){ 36 + vm.DialogaService.getCategories(function(categories){
44 vm.categories = categories; 37 vm.categories = categories;
45 }, function (error) { 38 }, function (error) {
46 vm.error = error; 39 vm.error = error;
src/app/pages/propostas/propostas.html
  1 +<div class="container">
  2 + <div class="row">
  3 + <div class="col-sm-12">
  4 + <div ncy-breadcrumb></div>
  5 + </div>
  6 + </div>
  7 +</div>
  8 +
1 <div class="container page--propostas"> 9 <div class="container page--propostas">
2 <h1>TODO: Home > Propostas</h1> 10 <h1>TODO: Home > Propostas</h1>
3 </div> 11 </div>
src/assets/images/icons/eye.png 0 → 100644

2.18 KB

src/assets/images/icons/greencheck.png 0 → 100644

1.79 KB

src/assets/images/icons/mail.png 0 → 100644

805 Bytes

src/assets/images/icons/ranking.png 0 → 100644

298 Bytes

src/assets/images/icons/redcross.png 0 → 100644

850 Bytes

src/assets/images/icons/social-facebook-contraste.png

1.34 KB

src/assets/images/icons/social-facebook-disabled.png

15.2 KB

src/assets/images/icons/social-facebook.png

1.52 KB | W: | H:

606 Bytes | W: | H:

  • 2-up
  • Swipe
  • Onion skin
src/assets/images/icons/social-flickr.png 0 → 100644

931 Bytes

src/assets/images/icons/social-google-plus-contraste.png

1.77 KB

src/assets/images/icons/social-google-plus-disabled.png

15.5 KB

src/assets/images/icons/social-google-plus.png

1.93 KB

src/assets/images/icons/social-googleplus.png 0 → 100644

962 Bytes

src/assets/images/icons/social-share.png 0 → 100644

1.36 KB

src/assets/images/icons/social-twitter-contraste.png

1.43 KB

src/assets/images/icons/social-twitter-disabled.png

15.4 KB

src/assets/images/icons/social-twitter.png

1.72 KB | W: | H:

780 Bytes | W: | H:

  • 2-up
  • Swipe
  • Onion skin
src/assets/images/icons/social-whatsapp-contraste.png

2.02 KB

src/assets/images/icons/social-whatsapp-disabled.png

15.7 KB

src/assets/images/icons/social-whatsapp.png

2.17 KB | W: | H:

1.09 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin
src/assets/images/icons/social-youtube.png 0 → 100644

623 Bytes

src/assets/images/icons/sprite.png

104 KB | W: | H:

105 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin
src/assets/images/icons/tema-agricultura.png 0 → 100644

3.1 KB

src/assets/images/icons/tema-cidadania-contraste.png

2.05 KB

src/assets/images/icons/tema-cidadania.png

1.63 KB

src/assets/images/icons/tema-cidades-contraste.png

2.04 KB

src/assets/images/icons/tema-cidades.png

1.59 KB | W: | H:

2.45 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin
src/assets/images/icons/tema-cultura-contraste.png

1.37 KB

src/assets/images/icons/tema-cultura.png

1.19 KB | W: | H:

1.86 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin
src/assets/images/icons/tema-desenvolvimento-produtivo.png 0 → 100644

2.88 KB

src/assets/images/icons/tema-desenvolvimento-social-contraste.png

2.56 KB

src/assets/images/icons/tema-desenvolvimento-social.png

2.3 KB

src/assets/images/icons/tema-educacao-contraste.png

2.99 KB

src/assets/images/icons/tema-esporte-contraste.png

1.78 KB

src/assets/images/icons/tema-esporte.png

1.13 KB | W: | H:

2.21 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin
src/assets/images/icons/tema-gestao-contraste.png

2.4 KB

src/assets/images/icons/tema-gestao-publica.png 0 → 100644

2.1 KB