Commit 1730f37c3a80e6acc671eae18f8f7121b1359cae

Authored by Leonardo Merlin
2 parents 4ff60ea5 53382f37

Merge branch 'feature-respostas'

.gitignore
... ... @@ -4,6 +4,7 @@ bower_components/
4 4 .idea/
5 5 .tmp/
6 6 dist/
  7 +coverage/
7 8 .editorconfig
8 9 script-staging.sh
9 10  
... ...
karma.conf.js
... ... @@ -13,12 +13,12 @@ function listFiles() {
13 13 });
14 14  
15 15 return wiredep(wiredepOptions).js
16   - .concat([
17   - path.join(conf.paths.src, '/app/**/*.module.js'),
18   - path.join(conf.paths.src, '/app/**/*.js'),
19   - path.join(conf.paths.src, '/**/*.spec.js'),
20   - path.join(conf.paths.src, '/**/*.mock.js'),
21   - path.join(conf.paths.src, '/**/*.html')
  16 + .concat([
  17 + path.join(conf.paths.src, '/app/**/*.module.js'),
  18 + path.join(conf.paths.src, '/app/**/*.js'),
  19 + path.join(conf.paths.src, '/**/*.spec.js'),
  20 + path.join(conf.paths.src, '/**/*.mock.js'),
  21 + path.join(conf.paths.src, '/**/*.html')
22 22 ]);
23 23 }
24 24  
... ... @@ -45,14 +45,26 @@ module.exports = function(config) {
45 45 browsers : ['PhantomJS'],
46 46  
47 47 plugins : [
48   - 'karma-phantomjs-launcher',
49   - 'karma-angular-filesort',
50   - 'karma-jasmine',
51   - 'karma-ng-html2js-preprocessor'
  48 + 'karma-jasmine',
  49 + 'karma-coverage',
  50 + 'karma-angular-filesort',
  51 + 'karma-ng-html2js-preprocessor',
  52 + 'karma-phantomjs-launcher',
  53 + 'karma-chrome-launcher',
  54 + 'karma-firefox-launcher'
52 55 ],
53 56  
54 57 preprocessors: {
55   - 'src/**/*.html': ['ng-html2js']
  58 + 'src/**/*.html': ['ng-html2js'],
  59 + 'src/app/**/*.js': ['coverage']
  60 + },
  61 +
  62 + reporters: ['progress', 'coverage'],
  63 +
  64 + coverageReporter: {
  65 + type : 'lcov', // HTML + LCOV
  66 + // type : 'cobertura', // supported by jenkins
  67 + dir : 'coverage/'
56 68 }
57 69 };
58 70  
... ...
package.json
... ... @@ -39,6 +39,9 @@
39 39 "jshint-stylish": "~2.0.0",
40 40 "karma": "~0.12.36",
41 41 "karma-angular-filesort": "~0.1.0",
  42 + "karma-chrome-launcher": "^0.2.1",
  43 + "karma-coverage": "^0.5.3",
  44 + "karma-firefox-launcher": "^0.1.7",
42 45 "karma-jasmine": "~0.3.5",
43 46 "karma-ng-html2js-preprocessor": "~0.1.2",
44 47 "karma-phantomjs-launcher": "~0.2.0",
... ...
src/app/components/app-navbar/app-navbar.html
... ... @@ -32,6 +32,7 @@
32 32 <li ui-sref-active="active"><a ui-sref="propostas">Propostas</a></li>
33 33 <li ui-sref-active="active"><a ui-sref="ranking">Ranking</a></li>
34 34 <li ui-sref-active="active"><a ui-sref="duvidas">Dúvidas</a></li>
  35 + <li ui-sref-active="active"><a ui-sref="respostas">Respostas</a></li>
35 36 <li role="separator" class="divider hidden-xs hidden-sm"><span>|</span></li>
36 37 <li class="dropdown" style="border: none;">
37 38 <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Compartilhar <span aria-hidden="true" class="icon icon-social-share-small"></span></a>
... ...
src/app/components/category-list/category-list.directive.js
... ... @@ -27,9 +27,11 @@
27 27 CategoryListController.prototype.init = function() {
28 28 var vm = this;
29 29  
  30 + // Default values
30 31 if(!vm.isCollapsed){
31 32 vm.isCollapsed = false;
32 33 }
  34 +
33 35 };
34 36  
35 37 CategoryListController.prototype._disableUnselect = function() {
... ...
src/app/components/category-list/category-list.html
1 1 <div class="category-list">
2 2 <nav class="navigation">
3 3 <h3 class="category-list--title" ng-click="vm.toogleList()">
4   - <span class="hidden-xs"><b>Programas</b> por Tema</span>
5   - <span class="visible-xs"><b>Filtrar</b> por Tema <span class="glyphicon glyphicon-filter pull-right"></span></span>
  4 + <!-- <span class="hidden-xs"><b>Programas</b> por Tema</span> -->
  5 + <!-- <span class="visible-xs"><b>Filtrar</b> por Tema <span class="glyphicon glyphicon-filter pull-right"></span></span> -->
  6 + <b>Filtrar</b> por Tema <span class="glyphicon glyphicon-filter pull-right"></span>
6 7 </h3>
7 8  
8 9 <!-- <div class="list-group ng-hide" ng-show="!vm.isCollapsed" ng-class="vm.selectedCategory.slug"> -->
... ...
src/app/components/proposal-box/proposal-box.directive.js
... ... @@ -90,17 +90,6 @@
90 90 }, 10);
91 91 };
92 92  
93   - ProposalBoxController.prototype.showContent = function(slug) {
94   - var vm = this;
95   -
96   - vm.$state.go('programa', {
97   - slug: slug,
98   - proposal_id: vm.proposal.id
99   - }, {
100   - location: true
101   - });
102   - };
103   -
104 93 ProposalBoxController.prototype.canVote = function() {
105 94 var vm = this;
106 95  
... ...
src/app/components/proposal-box/proposal-box.html
... ... @@ -145,16 +145,18 @@
145 145 <div class="proposal-box--content-inner">{{vm.proposal.abstract}}</div>
146 146 </div>
147 147 <div ng-hide="vm.showVote" class="proposal-box--join">
148   - <button
  148 + <a
149 149 class="btn btn-link color-theme-common-fg"
150 150 ng-if="vm.archived === false"
151   - ng-click="vm.showContent(vm.topic.slug)"
152   - >Participe</button>
153   - <button
  151 + ui-sref="programa({slug: vm.topic.slug, proposal_id: vm.proposal.id})"
  152 + ui-sref-opts="{location: true}"
  153 + >Participe</a>
  154 + <a
154 155 class="btn btn-link color-theme-common-fg"
155 156 ng-if="vm.archived === true"
156   - ng-click="vm.showContent(vm.topic.slug)"
157   - >Ir para o programa</button>
  157 + ui-sref="programa({slug: vm.topic.slug, proposal_id: vm.proposal.id})"
  158 + ui-sref-opts="{location: true}"
  159 + >Ir para o programa</a>
158 160 </div>
159 161 <div ng-show="vm.showVote" class="proposal-box--actions text-center">
160 162 <div class="row">
... ... @@ -185,7 +187,7 @@
185 187 </div>
186 188 </div>
187 189 </div>
188   - <div class="proposal-box--bottom text-center">
  190 + <div class="proposal-box--bottom text-center" ng-class="{archived: vm.archived}">
189 191 <div class="proposal-box--share">
190 192 <span>COMPARTILHE ESTA <b>PROPOSTA</b></span>
191 193 <div class="dropdown">
... ... @@ -198,11 +200,25 @@
198 200 class="dropdown-menu dropdown-menu-right"></social-share>
199 201 </div>
200 202 </div>
201   - <div class="proposal-box--ranking">
202   - <div class="proposal-box--ranking-inner">
203   - <span class="icon icon-small icon-ranking" aria-hidden="true"></span>
204   - <span>Colocação nos resultados:</span>
205   - <span>{{vm.proposal.ranking_position}}º</span>
  203 +
  204 + <div ng-if="vm.archived === true">
  205 + <div class="proposal-box--archived color-theme-bg-complementar-2">
  206 + <div class="proposal-box--archived-inner">
  207 + <a ui-sref="programa({slug: vm.topic.slug, proposal_id: vm.proposal.id})" ui-sref-opts="{location: true}">
  208 + Veja as respostas e compromissos assumidos
  209 + <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
  210 + </a>
  211 + </div>
  212 + </div>
  213 + </div>
  214 +
  215 + <div ng-if="vm.archived === false">
  216 + <div class="proposal-box--ranking">
  217 + <div class="proposal-box--ranking-inner">
  218 + <span class="icon icon-small icon-ranking" aria-hidden="true"></span>
  219 + <span>Colocação nos resultados:</span>
  220 + <span>{{vm.proposal.ranking_position}}º</span>
  221 + </div>
206 222 </div>
207 223 </div>
208 224 </div>
... ...
src/app/components/proposal-box/proposal-box.scss
... ... @@ -5,6 +5,8 @@
5 5 margin-bottom: 20px;
6 6 position: relative;
7 7  
  8 + .contraste & { background-color: #000 !important; outline: 1px solid #eee; }
  9 +
8 10 &.focus {
9 11 border: 7px solid #000;
10 12 border-radius: 12px;
... ... @@ -37,6 +39,12 @@
37 39 border-bottom-right-radius: 5px;
38 40 // overflow: hidden;
39 41 border-bottom: 5px solid #dadada;
  42 +
  43 + @each $category, $color in $categories {
  44 + .#{$category} &.archived {
  45 + border-bottom-color: map-get($categories-complementary-2, $category);
  46 + }
  47 + }
40 48 }
41 49  
42 50 &--theme {
... ... @@ -54,12 +62,25 @@
54 62 &--share {
55 63 padding: 15px 0;
56 64 background-color: #e8e8e8;
  65 +
  66 + .contraste & { background-color: #000 !important; outline: 1px solid #eee; }
57 67 }
58 68  
59   - &--ranking {
  69 + &--ranking,
  70 + &--archived {
60 71 font-weight: bold;
61 72 padding: 10px 0;
62 73 background-color: #dadada;
  74 +
  75 + .contraste & { background-color: #111 !important; outline: 1px solid #eee; }
  76 + }
  77 +
  78 + &--archived {
  79 + text-transform: uppercase;
  80 + font-size: 12px;
  81 + line-height: 23px;
  82 +
  83 + a { color: #fff; }
63 84 }
64 85  
65 86 .action-label {
... ...
src/app/index.route.js
... ... @@ -148,6 +148,18 @@
148 148 }
149 149 }
150 150 })
  151 + .state('respostas', {
  152 + url: '/respostas?tema&filtro',
  153 + reloadOnSearch: false,
  154 + ncyBreadcrumb: {label: 'Respostas'},
  155 + views: {
  156 + 'main': {
  157 + templateUrl: 'app/pages/respostas/respostas.html',
  158 + controller: 'RespostasPageController',
  159 + controllerAs: 'pageRespostas'
  160 + }
  161 + }
  162 + })
151 163 .state('sobre', {
152 164 url: '/sobre',
153 165 ncyBreadcrumb: {label: 'Sobre'},
... ...
src/app/index.scss
... ... @@ -75,13 +75,14 @@ $darken: 15%;
75 75 body {
76 76 font-family: "Open Sans", sans-serif;
77 77 &.contraste {
78   - color: #fff;
79   - background-color: #000;
  78 + color: #fff !important;
  79 + background-color: #000 !important;
80 80  
81 81 a,
82 82 .btn {
83   - color: #fff;
84   - background-color: #000;
  83 + color: #ff0 !important;
  84 + background-color: #000 !important;
  85 + text-decoration: underline !important;
85 86 }
86 87 }
87 88 }
... ... @@ -282,6 +283,8 @@ body {
282 283  
283 284 .contraste & .color-theme-fg { color: #fff; }
284 285 .contraste & .color-theme-bg { background-color: #000;}
  286 + .contraste & .color-theme-bg-complementar-1 { background-color: #111; outline: 1px solid #eee;}
  287 + .contraste & .color-theme-bg-complementar-2 { background-color: #222; outline: 1px solid #ddd;}
285 288 }
286 289 }
287 290  
... ... @@ -289,7 +292,9 @@ $common-color: #5E739E;
289 292 .color-theme-common-fg {color: $common-color; }
290 293 .color-theme-common-bg {background-color: $common-color; }
291 294 .color-fg-white {color: #fff; }
292   -.color-bg-gray {color: #ccc; }
  295 +.color-bg-white {background-color: #fff; }
  296 +.color-fg-gray {color: #ccc; }
  297 +.color-bg-gray {background-color: #ccc; }
293 298  
294 299 // Contraste
295 300 .contraste {
... ...
src/app/pages/programas/programa.controller.js
... ... @@ -275,4 +275,20 @@
275 275  
276 276 vm.proposalStatus = null;
277 277 };
  278 +
  279 + ProgramaPageController.prototype.toggleContentVisibility = function() {
  280 + var $sectionContent = angular.element('.section-content');
  281 +
  282 + if(!$sectionContent || $sectionContent.length === 0){
  283 + vm.$log.warn('".section-content" not found.');
  284 + return;
  285 + }
  286 +
  287 + if($sectionContent.is(':visible')){
  288 + $sectionContent.slideUp();
  289 + }else{
  290 + $sectionContent.slideDown();
  291 + angular.element('html,body').animate({scrollTop: $sectionContent.offset().top}, 'fast');
  292 + }
  293 + };
278 294 })();
... ...
src/app/pages/programas/programa.html
1 1 <div class="container">
2   - <div class="row">
3   - <div class="col-sm-12">
4   - <div ncy-breadcrumb></div>
  2 + <div class="row">
  3 + <div class="col-sm-12">
  4 + <div ncy-breadcrumb></div>
  5 + </div>
5 6 </div>
6   - </div>
7 7 </div>
8   -
9 8 <div class="page--program">
10   - <section>
11   - <div class="container">
12   - <div class="row">
13   - <div class="col-sm-12">
14   - <div ng-if="!pagePrograma.article && pagePrograma.loading" class="alert alert-info" role="alert">Carregando detalhes sobre o progama...</div>
15   - <div ng-if="!pagePrograma.article && pagePrograma.error" class="alert alert-warning" role="alert">Erro ao carregar o programa.</div>
  9 + <section ng-if="!pagePrograma.article">
  10 + <div class="container">
  11 + <div class="row">
  12 + <div class="col-sm-12">
  13 + <div ng-if="pagePrograma.loading" class="alert alert-info" role="alert">Carregando detalhes sobre o progama...</div>
  14 + <div ng-if="pagePrograma.error" class="alert alert-warning" role="alert">Erro ao carregar o programa.</div>
  15 + </div>
  16 + </div>
16 17 </div>
17   - </div>
18   - </div>
19   - </section>
20   -
21   - <div role="main" ng-class="pagePrograma.category.slug">
22   - <section ng-if="pagePrograma.article.body">
23   - <div class="container">
24   - <div class="row">
25   - <article class="program-preview">
26   - <!-- Preview > Titulo -->
27   - <div class="col-md-12">
28   - <h1 class="program-preview--title color-theme-fg">{{::pagePrograma.article.title}}</h1>
  18 + </section>
  19 + <div role="main" ng-class="pagePrograma.category.slug">
  20 + <section ng-if="pagePrograma.article.body">
  21 + <div class="container">
  22 + <div class="row">
  23 + <article class="program-preview" ng-class="{ 'program-preview--archived': pagePrograma.article.archived }">
  24 + <!-- Preview > Titulo -->
  25 + <div class="col-md-12">
  26 + <h1 class="program-preview--title color-theme-fg">{{::pagePrograma.article.title}}</h1>
  27 + </div>
  28 + <!-- Preview > coluna da esquerda -->
  29 + <div class="col-md-8">
  30 + <div class="program-preview--box contraste-box">
  31 + <div class="program-preview--banner" ng-style="{'background-image':'url( {{::pagePrograma.banner.src}} )'}"></div>
  32 + <div class="program-preview--box--content-wrapper">
  33 + <div class="program-preview--icon icon-wrapper-rounded color-theme-bg" ng-class="pagePrograma.category.slug">
  34 + <span class="icon" ng-class="'icon-tema-' + pagePrograma.category.slug"></span>
  35 + </div>
  36 + <div class="program-preview--abstract color-theme-fg" ng-if="pagePrograma.article.archived === false">
  37 + <h2>{{::stripHtml(pagePrograma.article.summary)}}</h2>
  38 + </div>
  39 + <div class="program-preview--abstract-details" ng-if="pagePrograma.article.archived === false">
  40 + <div ng-bind-html="pagePrograma.article.summaryExtended"></div>
  41 + </div>
  42 + <div class="program-preview--share">
  43 + <div class="program-preview--share-label">COMPARTILHE ESTE <b>PROGRAMA</b></div>
  44 + <div class="dropdown">
  45 + <button id="dropdown-share-btn" class="btn btn-link dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="Mostrar ou esconder a lista redes sociais para compartilhamento"><span class="icon icon-social-share-small" aria-hidden="true"></span></button>
  46 + <social-share social-url="pagePrograma.$state.href('programa', {slug: pagePrograma.article.slug}, {absolute: true})" social-text="pagePrograma.article.title" social-image="pagePrograma.banner.src" arrow-class="social-share--arrow" class="dropdown-menu dropdown-menu-right"></social-share>
  47 + </div>
  48 + </div>
  49 + <div class="program-preview--make-proposal" ng-if="pagePrograma.article.archived === false">
  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="pagePrograma.showProposalForm()">Faça uma proposta</button>
  54 + </div>
  55 + </div>
  56 + </div>
  57 + </div>
  58 + </div>
  59 + </div>
  60 + </div>
  61 + <!-- Preview > coluna da direita -->
  62 + <div class="col-md-4">
  63 + <div class="row">
  64 + <!-- Top Proposals -->
  65 + <div>
  66 + <!-- Loading Top Proposals -->
  67 + <div ng-if="pagePrograma.loadingTopProposals">
  68 + <div class="alert alert-info" role="alert">
  69 + Carregando propostas mais votadas...
  70 + </div>
  71 + </div>
  72 + <!-- Top Proposals > Carousel -->
  73 + <div class="col-xs-12" ng-if="!pagePrograma.loadingTopProposals && pagePrograma.proposalsTopRated && pagePrograma.proposalsTopRated.length > 0">
  74 + <h3 class="color-theme-fg">Propostas mais votadas</h3>
  75 + <proposal-carousel proposals="pagePrograma.proposalsTopRated" archived="pagePrograma.article.archived"></proposal-carousel>
  76 + </div>
  77 + </div>
  78 + <!-- Proposal Box -->
  79 + <div ng-if="!pagePrograma.article.archived">
  80 + <div class="col-xs-12" ng-if="!pagePrograma.loadingProposalBox && pagePrograma.randomProposal" ng-class="{'focused-proposal': !!pagePrograma.search.proposal_id}">
  81 + <h3 class="color-theme-fg">Apoie outras propostas</h3>
  82 + <proposal-box proposal="pagePrograma.randomProposal" topic="pagePrograma.article" category="pagePrograma.category" show-vote="true" focus="{{pagePrograma.search.proposal_id}}" do-vote="pagePrograma.vote(proposal_id, value)" archived="pagePrograma.article.archived"></proposal-box>
  83 + </div>
  84 + <!-- Loading Proposal Box -->
  85 + <div ng-if="pagePrograma.loadingProposalBox">
  86 + <div class="alert alert-info" role="alert">
  87 + Carregando propostas nesse programa...
  88 + </div>
  89 + </div>
  90 + </div>
  91 + <!-- No Proposals? okay! -->
  92 + <div ng-if="!pagePrograma.loadingTopProposals && !pagePrograma.loadingProposalBox">
  93 + <div class="col-xs-12" ng-if="!pagePrograma.randomProposal && !(pagePrograma.proposalsTopRated && pagePrograma.proposalsTopRated.length > 0)">
  94 + <h3>Programas sem propostas</h3>
  95 + <p>
  96 + Este programa ainda não possui nenhuma proposta.
  97 + <div class="button--themed">
  98 + <button type="button" class="btn btn-block" ng-click="pagePrograma.showProposalForm()">Faça uma proposta</button>
  99 + </div>
  100 + </p>
  101 + </div>
  102 + </div>
  103 + </div>
  104 + </div>
  105 + </article>
  106 + </div>
29 107 </div>
30   - <!-- Preview > coluna da esquerda -->
31   - <div class="col-md-8">
32   - <div class="program-preview--box contraste-box">
33   - <div class="program-preview--banner" ng-style="{'background-image':'url( {{::pagePrograma.banner.src}} )'}"></div>
34   - <div class="program-preview--box--content-wrapper">
35   - <div class="program-preview--icon icon-wrapper-rounded color-theme-bg" ng-class="pagePrograma.category.slug">
36   - <span class="icon" ng-class="'icon-tema-' + pagePrograma.category.slug"></span>
37   - </div>
38   - <div class="program-preview--abstract color-theme-fg">
39   - <h2>{{::stripHtml(pagePrograma.article.summary)}}</h2>
40   - </div>
41   - <div class="program-preview--abstract-details">
42   - <div ng-bind-html="pagePrograma.article.summaryExtended"></div>
43   - </div>
44   - <div class="program-preview--share">
45   - <div class="program-preview--share-label">COMPARTILHE ESTE <b>PROGRAMA</b></div>
46   - <div class="dropdown">
47   - <button id="dropdown-share-btn" class="btn btn-link dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="Mostrar ou esconder a lista redes sociais para compartilhamento"><span class="icon icon-social-share-small" aria-hidden="true"></span></button>
48   - <social-share
49   - social-url="pagePrograma.$state.href('programa', {slug: pagePrograma.article.slug}, {absolute: true})"
50   - social-text="pagePrograma.article.title"
51   - social-image="pagePrograma.banner.src"
52   - arrow-class="social-share--arrow"
53   - class="dropdown-menu dropdown-menu-right"
54   - ></social-share>
  108 + </section>
  109 + <section id="section-proposal-list" class="proposal-extended-section" style="display:none;" ng-if="pagePrograma.proposalsTopFive && pagePrograma.proposalsTopFive.length > 0">
  110 + <div class="container">
  111 + <div class="proposal-extended-section-header">
  112 + <h3 class="color-theme-fg">Resultados de propostas mais votadas</h3>
  113 + <button type="button" aria-label="Close" class="btn btn-close" ng-click="pagePrograma.hideProposalsList()">
  114 + <span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
  115 + </button>
  116 + </div>
  117 + <div class="proposal-extended-section-content">
  118 + <proposal-list proposals="pagePrograma.proposalsTopFive" archived="pagePrograma.article.archived"></proposal-list>
  119 + <div class="row text-center">
  120 + <div class="col-xs-12">
  121 + <a ui-sref="ranking({tema: pagePrograma.category.slug, programa: pagePrograma.article.slug})" class="btn btn-link">
  122 + <span ng-if="pagePrograma.total_proposals > 5">Veja todas as {{pagePrograma.total_proposals}} propostas</span>
  123 + </a>
  124 + </div>
55 125 </div>
56   - </div>
57   - <div class="program-preview--make-proposal">
  126 + </div>
  127 + </div>
  128 + </section>
  129 + <section id="section-proposal-form" class="proposal-extended-section" style="display:none;">
  130 + <div class="container">
  131 + <div class="proposal-extended-section-header">
  132 + <button type="button" aria-label="Close" class="btn btn-close" ng-click="pagePrograma.hideProposalForm()">
  133 + <span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
  134 + </button>
  135 + </div>
  136 + <div ng-if="!pagePrograma.$rootScope.currentUser">
  137 + <show-message type="'alert'" message="'Você não está logado!'" description="'Você precisa estar logado para enviar uma proposta.'"></show-message>
58 138 <div class="row">
59   - <div class="col-sm-6">
60   - <div class="button--themed" ng-if="!pagePrograma.article.archived">
61   - <button type="button" class="btn btn-block" ng-click="pagePrograma.showProposalForm()">Faça uma proposta</button>
  139 + <div class="col-sm-4"></div>
  140 + <div class="col-sm-8 text-center-sm">
  141 + <a ui-sref="entrar({redirect_uri: pagePrograma.sendProposalRedirectURI})">Clique aqui para ir para a página de login</a>
62 142 </div>
63   - <div ng-if="pagePrograma.article.archived">
64   - <button type="button"
65   - class="btn btn-block disabled"
66   - title="Este programa já foi analisado. Não está mais habilitado a receber novas propostas."
67   - ng-click="pagePrograma.showDetailAboutArchived = true"
68   - >Faça uma proposta</button>
  143 + </div>
  144 + </div>
  145 + <div ng-if="pagePrograma.$rootScope.currentUser">
  146 + <div class="proposal-extended-section-content">
  147 + <div ng-if="pagePrograma.proposalStatus === pagePrograma.PROPOSAL_STATUS.SUCCESS">
  148 + <show-message type="'success'" message="'Proposta enviada com sucesso!'" description="'Sua proposta foi enviada para a nossa equipe de moderação. Em aproximadamente 72 horas você receberá em seu endereço de e-mail uma resposta sobre a sua proposta.'"></show-message>
  149 + <div class="row">
  150 + <div class="col-sm-4"></div>
  151 + <div class="col-sm-8 text-center-sm">
  152 + <button type="button" class="btn btn-link" ng-click="pagePrograma.sendAnotherProposal()">
  153 + Clique aqui para enviar outra proposta
  154 + </button>
  155 + </div>
  156 + </div>
  157 + </div>
  158 + <div ng-if="pagePrograma.proposalStatus === pagePrograma.PROPOSAL_STATUS.SENDING">
  159 + Enviando...
  160 + </div>
  161 + <div ng-if="pagePrograma.proposalStatus === pagePrograma.PROPOSAL_STATUS.ERROR">
  162 + <show-message type="'error'" message="'Erro ' + pagePrograma.error.code + '!'" description="pagePrograma.error.message"></show-message>
  163 + <div class="row">
  164 + <div class="col-sm-4"></div>
  165 + <div class="col-sm-8 text-center-sm">
  166 + <button type="button" class="btn btn-link" ng-click="pagePrograma.sendAnotherProposal()">
  167 + Clique aqui para enviar outra proposta
  168 + </button>
  169 + </div>
  170 + </div>
  171 + </div>
  172 + <div ng-if="!pagePrograma.proposalStatus">
  173 + <cadastro-proposta program="pagePrograma.article" status="pagePrograma.proposalStatus"></cadastro-proposta>
69 174 </div>
70   - </div>
71   - <div class="col-sm-6" ng-show="pagePrograma.showDetailAboutArchived === true">
72   - <p>(&#9679;) Este programa está arquivado.<br>Não pode receber novas propostas.</p>
73   - </div>
74 175 </div>
75   - </div>
76 176 </div>
77   - </div>
78 177 </div>
79   - <!-- Preview > coluna da direita -->
80   - <div class="col-md-4">
81   - <div class="row">
82   -
83   - <!-- Top Proposals -->
84   - <div>
85   - <!-- Loading Top Proposals -->
86   - <div ng-if="pagePrograma.loadingTopProposals">
87   - <div class="alert alert-info" role="alert">
88   - Carregando propostas mais votadas...
  178 + </section>
  179 + <section id="section-archived-banner" class="color-theme-bg" ng-if="pagePrograma.article.archived">
  180 + <div class="container">
  181 + <div class="row">
  182 + <div class="col-sm-12">
  183 + <h2>
  184 + <div class="program-banner--icon-container" aria-hidden="true">
  185 + <div class="program-banner--icon icon-wrapper-rounded color-bg-white" ng-class="pagePrograma.category.slug">
  186 + <span class="icon" ng-class="'icon-discussion'"></span>
  187 + </div>
  188 + </div>
  189 + <span class="archived-banner--title1">As propostas para este programa já foram</span>
  190 + <br/>
  191 + <span class="archived-banner--title2">respondidas pelo governo! Confira as respostas:</span>
  192 + </h2>
89 193 </div>
90   - </div>
91   -
92   - <!-- Top Proposals > Carousel -->
93   - <div class="col-xs-12" ng-if="!pagePrograma.loadingTopProposals && pagePrograma.proposalsTopRated && pagePrograma.proposalsTopRated.length > 0">
94   - <h3 class="color-theme-fg">Propostas mais votadas</h3>
95   - <proposal-carousel
96   - proposals="pagePrograma.proposalsTopRated"
97   - archived="pagePrograma.article.archived"
98   - ></proposal-carousel>
99   - </div>
100 194 </div>
101   -
102   - <!-- Proposal Box -->
103   - <div ng-if="!pagePrograma.article.archived">
104   - <div class="col-xs-12" ng-if="!pagePrograma.loadingProposalBox && pagePrograma.randomProposal" ng-class="{'focused-proposal': !!pagePrograma.search.proposal_id}">
105   - <h3 class="color-theme-fg">Apoie outras propostas</h3>
106   - <proposal-box
107   - proposal="pagePrograma.randomProposal"
108   - topic="pagePrograma.article"
109   - category="pagePrograma.category"
110   - show-vote="true"
111   - focus="{{pagePrograma.search.proposal_id}}"
112   - do-vote="pagePrograma.vote(proposal_id, value)"
113   - archived="pagePrograma.article.archived"
114   - ></proposal-box>
115   - </div>
116   -
117   - <!-- Loading Proposal Box -->
118   - <div ng-if="pagePrograma.loadingProposalBox">
119   - <div class="alert alert-info" role="alert">
120   - Carregando propostas nesse programa...
  195 + </div>
  196 + </section>
  197 + <section id="section-response" ng-if="pagePrograma.article.archived">
  198 + <div ng-if="!pagePrograma.proposalsTopRated">
  199 + <div class="container">
  200 + <div class="row">
  201 + <div class="col-sm-12">
  202 + <div class="alert alert-info" role="alert">
  203 + Carregando propostas mais votadas...
  204 + </div>
  205 + </div>
121 206 </div>
122   - </div>
123   - </div>
124   -
125   - <!-- No Proposals? okay! -->
126   - <div ng-if="!pagePrograma.loadingTopProposals && !pagePrograma.loadingProposalBox">
127   - <div class="col-xs-12" ng-if="!pagePrograma.randomProposal && !(pagePrograma.proposalsTopRated && pagePrograma.proposalsTopRated.length > 0)">
128   - <h3>Programas sem propostas</h3>
129   - <p>
130   - Este programa ainda não possui nenhuma proposta.
131   - <div class="button--themed">
132   - <button type="button" class="btn btn-block" ng-click="pagePrograma.showProposalForm()">Faça uma proposta</button>
133   - </div>
134   - </p>
135   - </div>
136 207 </div>
137   - </div>
138   - </div>
139   - </article>
140   - </div>
141   - </div>
142   - </section>
143   -
144   - <section id="section-proposal-list" class="proposal-extended-section" style="display:none;" ng-if="pagePrograma.proposalsTopFive && pagePrograma.proposalsTopFive.length > 0">
145   - <div class="container">
146   - <div class="proposal-extended-section-header">
147   - <h3 class="color-theme-fg">Resultados de propostas mais votadas</h3>
148   - <button type="button" aria-label="Close" class="btn btn-close" ng-click="pagePrograma.hideProposalsList()">
149   - <span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
150   - </button>
151   - </div>
152   - <div class="proposal-extended-section-content">
153   - <proposal-list proposals="pagePrograma.proposalsTopFive" archived="pagePrograma.article.archived"></proposal-list>
154   - <div class="row text-center">
155   - <div class="col-xs-12">
156   - <a ui-sref="ranking({tema: pagePrograma.category.slug, programa: pagePrograma.article.slug})" class="btn btn-link">
157   - <span ng-if="pagePrograma.total_proposals > 5">Veja todas as {{pagePrograma.total_proposals}} propostas</span>
158   - </a>
159 208 </div>
160   - </div>
161   - </div>
162   - </div>
163   - </section>
164   -
165   - <section id="section-proposal-form" class="proposal-extended-section" style="display:none;">
166   - <div class="container">
167   - <div class="proposal-extended-section-header">
168   - <button type="button" aria-label="Close" class="btn btn-close" ng-click="pagePrograma.hideProposalForm()">
169   - <span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
170   - </button>
171   - </div>
172   - <div ng-if="!pagePrograma.$rootScope.currentUser">
173   - <show-message
174   - type="'alert'"
175   - message="'Você não está logado!'"
176   - description="'Você precisa estar logado para enviar uma proposta.'"
177   - ></show-message>
178   - <div class="row">
179   - <div class="col-sm-4"></div>
180   - <div class="col-sm-8 text-center-sm">
181   - <a ui-sref="entrar({redirect_uri: pagePrograma.sendProposalRedirectURI})">Clique aqui para ir para a página de login</a>
182   - </div>
183   - </div>
184   - </div>
185   - <div ng-if="pagePrograma.$rootScope.currentUser">
186   - <div class="proposal-extended-section-content">
187   - <div ng-if="pagePrograma.proposalStatus === pagePrograma.PROPOSAL_STATUS.SUCCESS">
188   - <show-message
189   - type="'success'"
190   - message="'Proposta enviada com sucesso!'"
191   - description="'Sua proposta foi enviada para a nossa equipe de moderação. Em aproximadamente 72 horas você receberá em seu endereço de e-mail uma resposta sobre a sua proposta.'"
192   - ></show-message>
193   - <div class="row">
194   - <div class="col-sm-4"></div>
195   - <div class="col-sm-8 text-center-sm">
196   - <button type="button" class="btn btn-link" ng-click="pagePrograma.sendAnotherProposal()">
197   - Clique aqui para enviar outra proposta
198   - </button>
  209 + <div ng-if="pagePrograma.proposalsTopRated">
  210 + <div class="sub-section" ng-repeat="proposal in pagePrograma.proposalsTopRated">
  211 + <div class="container">
  212 + <div class="row">
  213 + <div class="col-sm-12">
  214 + <h3 class="color-theme-fg">{{($index+1)}}a proposta mais votada:</h3>
  215 + <p>{{::proposal.abstract}}</p>
  216 +
  217 + <div class="button--themed">
  218 + <button class="btn btn-block">
  219 + Veja a resposta e o compromisso do governo
  220 + <div class="button-left-icon">
  221 + <span class="glyphicon glyphicon-chevron-down pull-right color-theme-common-fg" aria-hidden="true"></span>
  222 + </div>
  223 + </button>
  224 + </div>
  225 + </div>
  226 + </div>
  227 + </div>
199 228 </div>
200   - </div>
201   - </div>
202   - <div ng-if="pagePrograma.proposalStatus === pagePrograma.PROPOSAL_STATUS.SENDING">
203   - Enviando...
204 229 </div>
205   - <div ng-if="pagePrograma.proposalStatus === pagePrograma.PROPOSAL_STATUS.ERROR">
206   - <show-message
207   - type="'error'"
208   - message="'Erro ' + pagePrograma.error.code + '!'"
209   - description="pagePrograma.error.message"
210   - ></show-message>
211   - <div class="row">
212   - <div class="col-sm-4"></div>
213   - <div class="col-sm-8 text-center-sm">
214   - <button type="button" class="btn btn-link" ng-click="pagePrograma.sendAnotherProposal()">
215   - Clique aqui para enviar outra proposta
216   - </button>
  230 + <div class="response--context vertical-padding">
  231 + <div class="container">
  232 + <div class="row">
  233 + <div class="col-sm-5">
  234 + <div class="button--themed">
  235 + <a class="btn btn-block" ui-sref="respostas">
  236 + <span>Veja todas as propostas</span>
  237 + <br/>
  238 + <span>Respondidas pelo governo</span>
  239 + <span class="glyphicon glyphicon-chevron-right"></span>
  240 + </a>
  241 + </div>
  242 + </div>
  243 + <div class="col-sm-2"></div>
  244 + <div class="col-sm-5">
  245 + <div class="button--themed">
  246 + <button type="button" class="btn btn-block" ng-click="pagePrograma.toggleContentVisibility()">
  247 + <span>Informações sobre o programa</span>
  248 + <br/>
  249 + <span>"{{::pagePrograma.article.title}}"</span>
  250 + <span class="glyphicon glyphicon-chevron-right"></span>
  251 + </button>
  252 + </div>
  253 + </div>
  254 + </div>
217 255 </div>
218   - </div>
219 256 </div>
220   - <div ng-if="!pagePrograma.proposalStatus">
221   - <cadastro-proposta program="pagePrograma.article" status="pagePrograma.proposalStatus"></cadastro-proposta>
222   - </div>
223   - </div>
224   - </div>
225   - </div>
226   - </section>
227   -
228   - <section class="section-content">
229   - <article class="program-content" ng-if="pagePrograma.article" ng-class="pagePrograma.article.slug">
230   - <div ng-bind-html="pagePrograma.article.bodyTrusted"></div>
231   - </article>
232   - </section>
233   - </div>
  257 + </section>
  258 + <section class="section-content" ng-style="{ display: pagePrograma.article.archived ? 'none': 'block' }">
  259 + <article class="program-content" ng-if="pagePrograma.article" ng-class="pagePrograma.article.slug">
  260 + <div ng-bind-html="pagePrograma.article.bodyTrusted"></div>
  261 + </article>
  262 + </section>
  263 + </div>
234 264 </div>
... ...
src/app/pages/programas/programas.scss
... ... @@ -182,5 +182,91 @@
182 182 .proposal-extended-section-header {
183 183 position: relative;
184 184 }
  185 +
  186 + #section-archived-banner {
  187 + position: relative;
  188 + padding: 20px 0;
  189 + color: #fff;
  190 +
  191 + margin-top: 30px;
  192 +
  193 + h2 {
  194 + font-size: 28px;
  195 + line-height: 40px;
  196 +
  197 + @media screen and (max-width: $screen-md) {
  198 + font-size: 22px;
  199 + line-height: 30px;
  200 + }
  201 +
  202 + @media screen and (max-width: $screen-xs) {
  203 + font-size: 18px;
  204 + line-height: 24px;
  205 + }
  206 + }
  207 +
  208 + .program-banner--icon {
  209 + float: left;
  210 + margin-right: 20px;
  211 + width: 85px;
  212 + height: 85px;
  213 + overflow: hidden;
  214 +
  215 + .icon-discussion {
  216 + position: relative;
  217 + top: -3px;
  218 + left: -3px;
  219 + display: block;
  220 + width: 85px;
  221 + height: 85px;
  222 + background: red;
  223 + }
  224 + }
  225 +
  226 + .archived-banner--title2 {
  227 + font-weight: bold;
  228 + }
  229 + }
  230 +
  231 + #section-response {
  232 +
  233 + h3 {
  234 + font-weight: bold;
  235 + }
  236 + .sub-section{
  237 + padding: 20px 0;
  238 + &:nth-child(odd) {
  239 + background-color: #f1f1f1;
  240 + }
  241 +
  242 + &:nth-child(even) {
  243 + background-color: #ffffff;
  244 + }
  245 + }
  246 +
  247 + .button--themed {
  248 + position: relative;
  249 + max-width: 500px;
  250 +
  251 + button {
  252 + text-transform: uppercase;
  253 + letter-spacing: 1px;
  254 + }
  255 + }
  256 +
  257 + .button-left-icon {
  258 + position: absolute;
  259 + top: 15px;
  260 + right: 15px;
  261 +
  262 + .glyphicon {
  263 + position: relative;
  264 + top: -2px;
  265 + background-color: #fff;
  266 + padding: 6px 5px 5px 6px;
  267 + border-radius: 100%;
  268 + }
  269 + }
  270 + }
185 271 }
186 272  
... ...
src/app/pages/propostas/propostas.controller.js
... ... @@ -18,7 +18,7 @@
18 18  
19 19 vm.init();
20 20 vm.loadData();
21   - // vm.attachListeners(); // attach listeners after load data (SYNC)
  21 + vm.attachListeners();
22 22 vm.$rootScope.focusMainContent();
23 23  
24 24 $log.debug('PropostasPageController');
... ... @@ -31,11 +31,22 @@
31 31 vm.per_page = 10;
32 32 vm.themes = null;
33 33 vm.selectedTheme = null;
34   - vm.filtredPrograms = null;
35 34 vm.filtredProposals = null;
36 35 vm.query = null;
37 36 vm.search = vm.$location.search();
38 37  
  38 + if (vm.search.tema) {
  39 + vm._filtredByThemeSlug = vm.search.tema;
  40 + }
  41 +
  42 + if (vm.search.filtro) {
  43 + vm._filtredByQuery = vm.search.filtro;
  44 + }
  45 +
  46 + if (vm.search.tema || vm.search.filtro) {
  47 + vm.loadingFilter = true;
  48 + }
  49 +
39 50 vm.loading = null;
40 51 vm.error = null;
41 52 };
... ... @@ -56,12 +67,8 @@
56 67 vm.themes = themes;
57 68 vm.loadingThemes = false;
58 69 vm.loading = false;
59   -
60   - // REMOVED: function called twice.
61   - // vm.loadProposals(function() {
62   - // vm.attachListeners();
63   - // });
64   - vm.attachListeners();
  70 +
  71 + vm.filter();
65 72 }, function(error) {
66 73 vm.error = error;
67 74 vm.$log.error(error);
... ... @@ -70,30 +77,6 @@
70 77 });
71 78 };
72 79  
73   - // PropostasPageController.prototype.loadProposals = function(cb) {
74   - // var vm = this;
75   -
76   - // // load Proposals
77   - // vm.loadingProposals = true;
78   - // vm.DialogaService.searchProposals({
79   - // page: vm.page,
80   - // per_page: vm.per_page
81   - // }, function(data) {
82   - // vm.filtredProposals = data.articles;
83   - // vm.total_proposals = parseInt(data._obj.headers('total'));
84   -
85   - // vm.loadingProposals = false;
86   -
87   - // if (cb) {
88   - // cb();
89   - // }
90   - // }, function(error) {
91   - // vm.error = error;
92   - // vm.$log.error(error);
93   - // vm.loadingProposals = false;
94   - // });
95   - // };
96   -
97 80 PropostasPageController.prototype.attachListeners = function() {
98 81 var vm = this;
99 82  
... ... @@ -104,13 +87,19 @@
104 87 vm.$scope.$watch('pagePropostas.selectedTheme', function(newValue/*, oldValue*/) {
105 88 vm.search.tema = newValue ? newValue.slug : null;
106 89 vm.$location.search('tema', vm.search.tema);
107   - vm.filterProposals();
  90 +
  91 + if (!vm.loadingFilter) {
  92 + vm.filterProposals();
  93 + }
108 94 });
109 95  
110 96 vm.$scope.$watch('pagePropostas.query', function(newValue/*, oldValue*/) {
111 97 vm.search.filtro = newValue ? newValue : null;
112 98 vm.$location.search('filtro', vm.search.filtro);
113   - vm.filterProposals();
  99 +
  100 + if (!vm.loadingFilter) {
  101 + vm.filterProposals();
  102 + }
114 103 });
115 104 };
116 105  
... ... @@ -128,6 +117,35 @@
128 117 vm.filterProposals(pageIndex);
129 118 };
130 119  
  120 + PropostasPageController.prototype.filter = function() {
  121 + var vm = this;
  122 +
  123 + if (vm.loadingThemes || vm.loadingProposals) {
  124 + vm.$log.info('No proposals or themes loaded yet. Abort.');
  125 + return;
  126 + }
  127 +
  128 + if (vm._filtredByThemeSlug) {
  129 + var slug = vm._filtredByThemeSlug;
  130 +
  131 + vm.DialogaService.getThemeBySlug(slug, function(theme) {
  132 + vm.selectedTheme = theme;
  133 + }, function(error) {
  134 + vm.$log.error('Error when try to "getThemeBySlug"', error);
  135 + });
  136 + }
  137 +
  138 + if (vm._filtredByQuery) {
  139 + vm.query = vm._filtredByQuery;
  140 + }
  141 +
  142 + if (vm._filtredByThemeSlug || vm._filtredByQuery) {
  143 + vm.filterProposals();
  144 + vm.loadingFilter = false;
  145 + }
  146 +
  147 + };
  148 +
131 149 PropostasPageController.prototype.filterProposals = function(_page, _per_page) {
132 150 var vm = this;
133 151  
... ... @@ -165,8 +183,6 @@
165 183 PropostasPageController.prototype.submitSearch = function() {
166 184 var vm = this;
167 185  
168   - vm.loadingFilter = true;
169   -
170 186 // scroll to result grid
171 187 var $searchResult = angular.element('#search-result');
172 188 if ($searchResult && $searchResult.length > 0) {
... ...
src/app/pages/propostas/propostas.html
1 1 <div class="container">
2   - <div class="row">
3   - <div class="col-sm-12">
4   - <div ncy-breadcrumb></div>
  2 + <div class="row">
  3 + <div class="col-sm-12">
  4 + <div ncy-breadcrumb></div>
  5 + </div>
5 6 </div>
6   - </div>
7 7 </div>
8   -
9 8 <div class="page--propostas" role="main">
10   - <section class="section-info" ng-if="pagePropostas.loading || pagePropostas.error">
11   - <div class="container">
12   - <div class="row">
13   - <div class="col-md-12">
14   - <div ng-if="pagePropostas.loading && !pagePropostas.error">
15   - <div class="alert alert-info" role="alert">Carregando conteúdo...</div>
16   - </div>
17   -
18   - <div ng-if="pagePropostas.error">
19   - <div class="alert alert-danger" role="alert">
20   - Erro ao carregar o conteúdo principal.
  9 + <section class="section-info" ng-if="pagePropostas.loading || pagePropostas.error">
  10 + <div class="container">
  11 + <div class="row">
  12 + <div class="col-md-12">
  13 + <div ng-if="pagePropostas.loading && !pagePropostas.error">
  14 + <div class="alert alert-info" role="alert">Carregando conteúdo...</div>
  15 + </div>
  16 + <div ng-if="pagePropostas.error">
  17 + <div class="alert alert-danger" role="alert">
  18 + Erro ao carregar o conteúdo principal.
  19 + </div>
  20 + </div>
  21 + </div>
21 22 </div>
22   - </div>
23 23 </div>
24   - </div>
25   - </div>
26   - </section>
27   -
28   - <section class="section--header" ng-if="pagePropostas.filtredProposals || pagePropostas.themes">
29   - <div class="container">
30   - <div class="row">
31   - <div class="col-sm-12">
32   - <h1>Propostas</h1>
33   - </div>
34   - </div>
35   - </div>
36   - </section>
37   -
38   - <section class="section--articles section-gray section-space-up" ng-if="pagePropostas.filtredProposals || pagePropostas.themes">
39   - <div class="container">
40   - <div id="lista-de-propostas" class="row">
41   - <div class="col-sm-4 col-md-3">
42   - <div class="row visible-xs">
43   - <div class="col-xs-12">
44   - <div class="input-group input-group-lg input-group-search">
45   - <label for="articleQueryFilter" class="control-label sr-only">Buscar propostas:</label>
46   - <input id="articleQueryFilter" type="search" class="form-control input-search" ng-model="pagePropostas.query" placeholder="Buscar propostas" aria-label="Buscar propostas">
47   - <span class="input-group-btn">
48   - <button type="button" class="btn btn-default" ng-click="pagePropostas.submitSearch()">
49   - <span class="icon-circle icon-small color-theme-common-bg">
50   - <span class="glyphicon glyphicon-search"></span>
51   - </span>
52   - <span class="sr-only">Buscar</span>
53   - </button>
54   - </span>
55   - </div>
56   - <br/>
57   - </div>
58   - </div>
59   - <div ng-if="pagePropostas.themes">
60   - <category-list categories="pagePropostas.themes" selected-category="pagePropostas.selectedTheme"></category-list>
61   - </div>
62   - <div ng-if="!pagePropostas.themes && pagePropostas.loadingThemes">
63   - <div class="alert alert-info" role="alert">
64   - Carregando temas.
  24 + </section>
  25 + <section class="section--header" ng-if="pagePropostas.filtredProposals || pagePropostas.themes">
  26 + <div class="container">
  27 + <div class="row">
  28 + <div class="col-sm-12">
  29 + <h1>Propostas</h1>
  30 + </div>
65 31 </div>
66   - </div>
67   - <div ng-if="!pagePropostas.themes && pagePropostas.themesError">
68   - <div class="alert alert-danger" role="alert">
69   - Não foi possível carregar a lista de temas neste momento.
70   - </div>
71   - </div>
72 32 </div>
73   - <div class="col-sm-8 col-md-9">
74   - <div class="row hidden-xs" ng-if="pagePropostas.filtredProposals">
75   - <div class="col-xs-12">
76   - <div class="input-group input-group-lg input-group-search">
77   - <label for="articleQueryFilter" class="control-label sr-only">Buscar propostas:</label>
78   - <input id="articleQueryFilter" type="search" class="form-control input-search" ng-model="pagePropostas.query" placeholder="Buscar propostas" aria-label="Buscar propostas">
79   - <span class="input-group-btn">
80   - <button type="button" class="btn btn-default" ng-click="pagePropostas.submitSearch()">
81   - <span class="icon-circle icon-small color-theme-common-bg">
82   - <span class="glyphicon glyphicon-search"></span>
83   - </span>
84   - <span class="sr-only">Buscar</span>
85   - </button>
86   - </span>
87   - </div>
88   - </div>
89   - </div>
90   -
91   - <div id="search-result" class="row" ng-if="pagePropostas.filtredProposals">
92   - <div class="col-sm-12">
93   - <header class="header">
94   - <h2>Total de Propostas: "<b>{{pagePropostas.total_proposals}} propostas</b>"</h2>
95   - </header>
96   - </div>
97   - </div>
98   -
99   - <div class="row">
100   - <div class="col-sm-12" ng-if="!pagePropostas.loadingProposals && pagePropostas.filtredProposals && pagePropostas.total_proposals">
101   - <proposal-grid proposals="pagePropostas.filtredProposals"></proposal-grid>
102   - <app-paginator
103   - page="pagePropostas.page"
104   - per-page="pagePropostas.per_page"
105   - total="pagePropostas.total_proposals"
106   - change-page="pagePropostas.changePage(pageIndex)"
107   - ></app-paginator>
  33 + </section>
  34 + <section class="section--articles section-gray section-space-up" ng-if="pagePropostas.filtredProposals || pagePropostas.themes">
  35 + <div class="container">
  36 + <div id="lista-de-propostas" class="row">
  37 + <div class="col-sm-4 col-md-3">
  38 + <div class="row visible-xs">
  39 + <div class="col-xs-12">
  40 + <div class="input-group input-group-lg input-group-search">
  41 + <label for="articleQueryFilter" class="control-label sr-only">Buscar propostas:</label>
  42 + <input id="articleQueryFilter" type="search" class="form-control input-search" ng-model="pagePropostas.query" placeholder="Buscar propostas" aria-label="Buscar propostas">
  43 + <div class="input-group-btn">
  44 + <button type="button" class="btn btn-default" ng-click="pagePropostas.submitSearch()">
  45 + <div class="icon-circle icon-small color-theme-common-bg">
  46 + <span class="glyphicon glyphicon-search"></span>
  47 + </div>
  48 + <span class="sr-only">Buscar</span>
  49 + </button>
  50 + </div>
  51 + </div>
  52 + <br/>
  53 + </div>
  54 + </div>
  55 + <div ng-if="pagePropostas.themes">
  56 + <category-list categories="pagePropostas.themes" selected-category="pagePropostas.selectedTheme"></category-list>
  57 + </div>
  58 + <div ng-if="!pagePropostas.themes && pagePropostas.loadingThemes">
  59 + <div class="alert alert-info" role="alert">
  60 + Carregando temas.
  61 + </div>
  62 + </div>
  63 + <div ng-if="!pagePropostas.themes && pagePropostas.themesError">
  64 + <div class="alert alert-danger" role="alert">
  65 + Não foi possível carregar a lista de temas neste momento.
  66 + </div>
  67 + </div>
  68 + </div>
  69 + <div class="col-sm-8 col-md-9">
  70 + <div class="row hidden-xs" ng-if="pagePropostas.filtredProposals">
  71 + <div class="col-xs-12">
  72 + <div class="input-group input-group-lg input-group-search">
  73 + <label for="articleQueryFilter" class="control-label sr-only">Buscar propostas:</label>
  74 + <input id="articleQueryFilter" type="search" class="form-control input-search" ng-model="pagePropostas.query" placeholder="Buscar propostas" aria-label="Buscar propostas">
  75 + <div class="input-group-btn">
  76 + <button type="button" class="btn btn-default" ng-click="pagePropostas.submitSearch()">
  77 + <div class="icon-circle icon-small color-theme-common-bg">
  78 + <span class="glyphicon glyphicon-search"></span>
  79 + </div>
  80 + <span class="sr-only">Buscar</span>
  81 + </button>
  82 + </div>
  83 + </div>
  84 + </div>
  85 + </div>
  86 + <div id="search-result" class="row" ng-if="pagePropostas.filtredProposals">
  87 + <div class="col-sm-12">
  88 + <header class="header">
  89 + <h2>Total de Propostas: "<b>{{pagePropostas.total_proposals}} propostas</b>"</h2>
  90 + </header>
  91 + </div>
  92 + </div>
  93 + <div class="row">
  94 + <div class="col-sm-12" ng-if="!pagePropostas.loadingProposals && pagePropostas.filtredProposals && pagePropostas.total_proposals">
  95 + <proposal-grid proposals="pagePropostas.filtredProposals"></proposal-grid>
  96 + <app-paginator page="pagePropostas.page" per-page="pagePropostas.per_page" total="pagePropostas.total_proposals" change-page="pagePropostas.changePage(pageIndex)"></app-paginator>
  97 + </div>
  98 + <div ng-if="pagePropostas.loadingProposals">
  99 + <div class="alert alert-info" role="alert">
  100 + Carregando propostas.
  101 + </div>
  102 + </div>
  103 + <div ng-if="!pagePropostas.loadingProposals && pagePropostas.proposalsError">
  104 + <div class="alert alert-danger" role="alert">
  105 + Não foi possível carregar a lista de propostas neste momento.
  106 + </div>
  107 + </div>
  108 + </div>
  109 + </div>
108 110 </div>
109   - <div ng-if="pagePropostas.loadingProposals">
110   - <div class="alert alert-info" role="alert">
111   - Carregando propostas.
112   - </div>
113   - </div>
114   - <div ng-if="!pagePropostas.loadingProposals && pagePropostas.proposalsError">
115   - <div class="alert alert-danger" role="alert">
116   - Não foi possível carregar a lista de propostas neste momento.
117   - </div>
118   - </div>
119   - </div>
120 111 </div>
121   - </div>
122   - </div>
123   - </section>
  112 + </section>
124 113 </div>
... ...
src/app/pages/respostas/respostas.controller.js 0 → 100644
... ... @@ -0,0 +1,196 @@
  1 +(function() {
  2 + 'use strict';
  3 +
  4 + angular
  5 + .module('dialoga')
  6 + .controller('RespostasPageController', RespostasPageController);
  7 +
  8 + /** @ngInject */
  9 + function RespostasPageController(DialogaService, $scope, $rootScope, $location, $filter, $log) {
  10 + var vm = this;
  11 +
  12 + vm.DialogaService = DialogaService;
  13 + vm.$scope = $scope;
  14 + vm.$rootScope = $rootScope;
  15 + vm.$location = $location;
  16 + vm.$filter = $filter;
  17 + vm.$log = $log;
  18 +
  19 + vm.init();
  20 + vm.loadData();
  21 + vm.attachListeners();
  22 + vm.$rootScope.focusMainContent();
  23 +
  24 + $log.debug('RespostasPageController');
  25 + }
  26 +
  27 + RespostasPageController.prototype.init = function() {
  28 + var vm = this;
  29 +
  30 + vm.page = 1;
  31 + vm.per_page = 10;
  32 + vm.themes = null;
  33 + vm.selectedTheme = null;
  34 + vm.filtredProposals = null;
  35 + vm.query = null;
  36 + vm.search = vm.$location.search();
  37 +
  38 + if (vm.search.tema) {
  39 + vm._filtredByThemeSlug = vm.search.tema;
  40 + }
  41 +
  42 + if (vm.search.filtro) {
  43 + vm._filtredByQuery = vm.search.filtro;
  44 + }
  45 +
  46 + if (vm.search.tema || vm.search.filtro) {
  47 + vm.loadingFilter = true;
  48 + }
  49 +
  50 + vm.loading = null;
  51 + vm.error = null;
  52 + };
  53 +
  54 + RespostasPageController.prototype.loadData = function() {
  55 + var vm = this;
  56 +
  57 + vm.loading = true;
  58 +
  59 + // Behaviour:
  60 + // 1. Load themes
  61 + // 1. Load Proposals per_page
  62 + // END.
  63 +
  64 + // 1. Load themes
  65 + vm.loadingThemes = true;
  66 + vm.DialogaService.getThemes(function(themes) {
  67 + vm.themes = themes;
  68 + vm.loadingThemes = false;
  69 + vm.loading = false;
  70 +
  71 + vm.filter();
  72 + }, function(error) {
  73 + vm.error = error;
  74 + vm.$log.error(error);
  75 + vm.loadingThemes = false;
  76 + vm.loading = false;
  77 + });
  78 + };
  79 +
  80 + RespostasPageController.prototype.attachListeners = function() {
  81 + var vm = this;
  82 +
  83 + vm.$scope.$on('change-selectedCategory', function(event, selectedCategory) {
  84 + vm.selectedTheme = selectedCategory;
  85 + });
  86 +
  87 + vm.$scope.$watch('pageRespostas.selectedTheme', function(newValue/*, oldValue*/) {
  88 + vm.search.tema = newValue ? newValue.slug : null;
  89 + vm.$location.search('tema', vm.search.tema);
  90 +
  91 + if (!vm.loadingFilter) {
  92 + vm.filterProposals();
  93 + }
  94 + });
  95 +
  96 + vm.$scope.$watch('pageRespostas.query', function(newValue/*, oldValue*/) {
  97 + vm.search.filtro = newValue ? newValue : null;
  98 + vm.$location.search('filtro', vm.search.filtro);
  99 +
  100 + if (!vm.loadingFilter) {
  101 + vm.filterProposals();
  102 + }
  103 + });
  104 + };
  105 +
  106 + RespostasPageController.prototype.resetFilterValues = function() {
  107 + var vm = this;
  108 +
  109 + vm.query = null;
  110 + vm.selectedTheme = null;
  111 + };
  112 +
  113 + RespostasPageController.prototype.changePage = function(pageIndex) {
  114 + var vm = this;
  115 +
  116 + vm.page = pageIndex;
  117 + vm.filterProposals(pageIndex);
  118 + };
  119 +
  120 + RespostasPageController.prototype.filter = function() {
  121 + var vm = this;
  122 +
  123 + if (vm.loadingThemes || vm.loadingProposals) {
  124 + vm.$log.info('No proposals or themes loaded yet. Abort.');
  125 + return;
  126 + }
  127 +
  128 + if (vm._filtredByThemeSlug) {
  129 + var slug = vm._filtredByThemeSlug;
  130 +
  131 + vm.DialogaService.getThemeBySlug(slug, function(theme) {
  132 + vm.selectedTheme = theme;
  133 + }, function(error) {
  134 + vm.$log.error('Error when try to "getThemeBySlug"', error);
  135 + });
  136 + }
  137 +
  138 + if (vm._filtredByQuery) {
  139 + vm.query = vm._filtredByQuery;
  140 + }
  141 +
  142 + if (vm._filtredByThemeSlug || vm._filtredByQuery) {
  143 + vm.filterProposals();
  144 + vm.loadingFilter = false;
  145 + }
  146 + };
  147 +
  148 + RespostasPageController.prototype.filterProposals = function(_page, _per_page) {
  149 + var vm = this;
  150 +
  151 + if (vm.loadingProposals){
  152 + vm.$log.debug('Content is not loaded yet.');
  153 + return;
  154 + }
  155 +
  156 + var page = _page || vm.page;
  157 + var per_page = _per_page || vm.per_page;
  158 + var query = vm.query;
  159 + var params = {
  160 + page: page,
  161 + per_page: per_page,
  162 + archived: true
  163 + };
  164 +
  165 + if (vm.selectedTheme) {
  166 + params.category_ids = vm.selectedTheme.id;
  167 + }
  168 +
  169 + if (query) {params.query = query; }
  170 +
  171 + vm.loadingProposals = true;
  172 + vm.DialogaService.searchProposals(params, function(data){
  173 + vm.total_proposals = parseInt(data._obj.headers('total'));
  174 + vm.filtredProposals = data.articles;
  175 + vm.loadingProposals = false;
  176 + }, function (error) {
  177 + vm.error = error;
  178 + vm.$log.error(error);
  179 + vm.loadingProposals = false;
  180 + });
  181 + };
  182 +
  183 + RespostasPageController.prototype.submitSearch = function() {
  184 + var vm = this;
  185 +
  186 + // scroll to result grid
  187 + var $searchResult = angular.element('#search-result');
  188 + if ($searchResult && $searchResult.length > 0) {
  189 + angular.element('html,body').animate({scrollTop: $searchResult.offset().top}, 'fast');
  190 + vm.filterProposals();
  191 + }else {
  192 + vm.$log.warn('#search-result element not found.');
  193 + }
  194 + };
  195 +
  196 +})();
... ...
src/app/pages/respostas/respostas.html 0 → 100644
... ... @@ -0,0 +1,117 @@
  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 +<div class="page--respostas" role="main">
  9 + <section class="section-info" ng-if="pageRespostas.loading || pageRespostas.error">
  10 + <div class="container">
  11 + <div class="row">
  12 + <div class="col-md-12">
  13 + <div ng-if="pageRespostas.loading && !pageRespostas.error">
  14 + <div class="alert alert-info" role="alert">Carregando conteúdo...</div>
  15 + </div>
  16 + <div ng-if="pageRespostas.error">
  17 + <div class="alert alert-danger" role="alert">
  18 + Erro ao carregar o conteúdo principal.
  19 + </div>
  20 + </div>
  21 + </div>
  22 + </div>
  23 + </div>
  24 + </section>
  25 + <section class="section--header" ng-if="pageRespostas.filtredProposals || pageRespostas.themes">
  26 + <div class="container">
  27 + <div class="row">
  28 + <div class="col-sm-12">
  29 + <h1>O Dialoga Brasil já respondeu às solicitações!</h1>
  30 + <p>
  31 + Vários programas contaram com centenas de participações e elas foram respondidas pelo governo.
  32 + Confira abaixo as propostas que foram respondidas:
  33 + </p>
  34 + </div>
  35 + </div>
  36 + </div>
  37 + </section>
  38 + <section class="section--articles section-gray section-space-up" ng-if="pageRespostas.filtredProposals || pageRespostas.themes">
  39 + <div class="container">
  40 + <div id="lista-de-respostas" class="row">
  41 + <div class="col-sm-4 col-md-3">
  42 + <div class="row visible-xs">
  43 + <div class="col-xs-12">
  44 + <div class="input-group input-group-lg input-group-search">
  45 + <label for="articleQueryFilter" class="control-label sr-only">Buscar respostas:</label>
  46 + <input id="articleQueryFilter" type="search" class="form-control input-search" ng-model="pageRespostas.query" placeholder="Buscar respostas" aria-label="Buscar respostas">
  47 + <div class="input-group-btn">
  48 + <button type="button" class="btn btn-default" ng-click="pageRespostas.submitSearch()">
  49 + <div class="icon-circle icon-small color-theme-common-bg">
  50 + <span class="glyphicon glyphicon-search"></span>
  51 + </div>
  52 + <span class="sr-only">Buscar</span>
  53 + </button>
  54 + </div>
  55 + </div>
  56 + <br/>
  57 + </div>
  58 + </div>
  59 + <div ng-if="pageRespostas.themes">
  60 + <category-list categories="pageRespostas.themes" selected-category="pageRespostas.selectedTheme"></category-list>
  61 + </div>
  62 + <div ng-if="!pageRespostas.themes && pageRespostas.loadingThemes">
  63 + <div class="alert alert-info" role="alert">
  64 + Carregando temas.
  65 + </div>
  66 + </div>
  67 + <div ng-if="!pageRespostas.themes && pageRespostas.themesError">
  68 + <div class="alert alert-danger" role="alert">
  69 + Não foi possível carregar a lista de temas neste momento.
  70 + </div>
  71 + </div>
  72 + </div>
  73 + <div class="col-sm-8 col-md-9">
  74 + <div class="row hidden-xs" ng-if="pageRespostas.filtredProposals">
  75 + <div class="col-xs-12">
  76 + <div class="input-group input-group-lg input-group-search">
  77 + <label for="articleQueryFilter" class="control-label sr-only">Buscar propostas:</label>
  78 + <input id="articleQueryFilter" type="search" class="form-control input-search" ng-model="pageRespostas.query" placeholder="Buscar respostas" aria-label="Buscar respostas">
  79 + <div class="input-group-btn">
  80 + <button type="button" class="btn btn-default" ng-click="pageRespostas.submitSearch()">
  81 + <div class="icon-circle icon-small color-theme-common-bg">
  82 + <span class="glyphicon glyphicon-search"></span>
  83 + </div>
  84 + <span class="sr-only">Buscar</span>
  85 + </button>
  86 + </div>
  87 + </div>
  88 + </div>
  89 + </div>
  90 + <div id="search-result" class="row" ng-if="pageRespostas.filtredProposals">
  91 + <div class="col-sm-12">
  92 + <header class="header">
  93 + <h2>Total de Propostas: "<b>{{pageRespostas.total_proposals}} propostas</b>"</h2>
  94 + </header>
  95 + </div>
  96 + </div>
  97 + <div class="row">
  98 + <div class="col-sm-12" ng-if="!pageRespostas.loadingProposals && pageRespostas.filtredProposals && pageRespostas.total_proposals">
  99 + <proposal-grid proposals="pageRespostas.filtredProposals"></proposal-grid>
  100 + <app-paginator page="pageRespostas.page" per-page="pageRespostas.per_page" total="pageRespostas.total_proposals" change-page="pageRespostas.changePage(pageIndex)"></app-paginator>
  101 + </div>
  102 + <div ng-if="pageRespostas.loadingProposals">
  103 + <div class="alert alert-info" role="alert">
  104 + Carregando propostas.
  105 + </div>
  106 + </div>
  107 + <div ng-if="!pageRespostas.loadingProposals && pageRespostas.proposalsError">
  108 + <div class="alert alert-danger" role="alert">
  109 + Não foi possível carregar a lista de propostas neste momento.
  110 + </div>
  111 + </div>
  112 + </div>
  113 + </div>
  114 + </div>
  115 + </div>
  116 + </section>
  117 +</div>
... ...
src/app/pages/respostas/respostas.scss 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +.page--respostas {
  2 + .proposal-box--middle {
  3 + background-color: #fff;
  4 + }
  5 +
  6 + .topics-select--wrapper {
  7 + margin: 20px 0;
  8 + }
  9 +}
... ...