Commit 250eedcee493512273873f26563e8e415487892e

Authored by Rafael Diego
2 parents 82bc7b71 8dbfc7f0

Merge branch 'rafael' of gitlab.com:participa/discussion-app into rafael

Showing 76 changed files with 1258 additions and 659 deletions   Show diff stats
gulp/build.js
... ... @@ -43,9 +43,13 @@ gulp.task('html', ['inject', 'partials'], function () {
43 43 .pipe(assets = $.useref.assets())
44 44 .pipe($.rev())
45 45 .pipe(jsFilter)
46   - .pipe($.if($.util.env.server === 'production', $.replace('$logProvider.debugEnabled(true);', '$logProvider.debugEnabled(false);')))
47   - .pipe($.if($.util.env.server === 'production', $.replace('http://hom.dialoga.gov.br', 'http://login.dialoga.gov.br')))
48   - .pipe($.if($.util.env.server === 'production', $.replace('http://hom.login.dialoga.gov.br', 'http://login.dialoga.gov.br')))
  46 + // production
  47 + .pipe($.if($.util.env.production, $.replace('$logProvider.debugEnabled(true);', '$logProvider.debugEnabled(false);')))
  48 + .pipe($.if($.util.env.production, $.replace('http://hom.dialoga.gov.br', 'http://login.dialoga.gov.br')))
  49 + .pipe($.if($.util.env.production, $.replace('http://hom.login.dialoga.gov.br', 'http://login.dialoga.gov.br')))
  50 + // staging
  51 + .pipe($.if($.util.env.staging, $.replace('http://dialoga.gov.br', 'http://hom.dialoga.gov.br')))
  52 + .pipe($.if($.util.env.staging, $.replace('http://login.dialoga.gov.br', 'http://hom.login.dialoga.gov.br')))
49 53 .pipe($.ngAnnotate())
50 54 .pipe($.uglify({ preserveComments: $.uglifySaveLicense })).on('error', conf.errorHandler('Uglify'))
51 55 .pipe(jsFilter.restore())
... ...
src/app/components/app-footer/app-footer.html
... ... @@ -2,7 +2,6 @@
2 2 <div class="container">
3 3 <div class="row">
4 4 <div class="col-xs-12 text-center">
5   - <a id="termos-de-uso" ui-sref="termos-de-uso">Termos de uso</a>
6 5 <a href="#header" style="position:absolute;right:0;top:-10px;" ng-click="scrollTo('#header')">Voltar para o topo</a>
7 6 </div>
8 7 </div>
... ...
src/app/components/app-paginator/app-paginator.directive.js 0 → 100644
... ... @@ -0,0 +1,71 @@
  1 +(function() {
  2 + 'use strict';
  3 +
  4 + angular
  5 + .module('dialoga')
  6 + .directive('appPaginator', appPaginator);
  7 +
  8 + /** @ngInject */
  9 + function appPaginator() {
  10 +
  11 + /** @ngInject */
  12 + function AppPaginatorController($log) {
  13 + var vm = this;
  14 +
  15 + vm.$log = $log;
  16 +
  17 + vm.init();
  18 +
  19 + $log.debug('AppPaginatorController');
  20 + }
  21 +
  22 + AppPaginatorController.prototype.init = function() {
  23 + var vm = this;
  24 +
  25 + vm.page = vm.page || 1;
  26 + vm.perPage = vm.perPage || 20;
  27 + vm.total = vm.total || 0;
  28 +
  29 + if ((vm.total % vm.perPage) === 0) {
  30 + vm.pages = vm.total / vm.perPage;
  31 + } else {
  32 + vm.pages = (vm.total / vm.perPage) + 1;
  33 + }
  34 +
  35 + vm.arraypages = new Array(Math.floor(vm.pages));
  36 + };
  37 +
  38 + AppPaginatorController.prototype.showPage = function(pageIndex) {
  39 + var vm = this;
  40 +
  41 + if (pageIndex < 1) {
  42 + pageIndex = 1;
  43 + }
  44 +
  45 + if (pageIndex > vm.pages) {
  46 + pageIndex = vm.pages;
  47 + }
  48 +
  49 + if (vm.changePage) {
  50 + vm.changePage({pageIndex: pageIndex});
  51 + }
  52 + };
  53 +
  54 + var directive = {
  55 + restrict: 'E',
  56 + templateUrl: 'app/components/app-paginator/app-paginator.html',
  57 + scope: {
  58 + page: '=',
  59 + perPage: '=',
  60 + total: '=',
  61 + changePage: '&'
  62 + },
  63 + controller: AppPaginatorController,
  64 + controllerAs: 'vm',
  65 + bindToController: true
  66 + };
  67 +
  68 + return directive;
  69 + }
  70 +
  71 +})();
... ...
src/app/components/app-paginator/app-paginator.html 0 → 100644
... ... @@ -0,0 +1,17 @@
  1 +<nav class="app-paginator" ng-if="vm.arraypages.length > 1">
  2 + <ul class="pagination">
  3 + <li ng-style="{'visibility': (vm.page === 1) ? 'hidden' : 'visible'}">
  4 + <a class="btn-pagination" href="#" aria-label="Previous" ng-click="vm.showPage(vm.page-1)">
  5 + <span aria-hidden="true" class="glyphicon glyphicon-chevron-left pagination-icon"></span>
  6 + </a>
  7 + </li>
  8 + <li ng-repeat="paginas in vm.arraypages track by $index" ng-class="{ 'active' : ($index) === (vm.page - 1) }" >
  9 + <a class="btn-pagination" href="#" ng-click="vm.showPage($index + 1)">{{::($index)+1}}</a>
  10 + </li>
  11 + <li ng-style="{'visibility': (vm.page === vm.arraypages.length) ? 'hidden' : 'visible'}">
  12 + <a class="btn-pagination" href="#" aria-label="Next" ng-click="vm.showPage(vm.page+1)">
  13 + <span aria-hidden="true" class="glyphicon glyphicon-chevron-right pagination-icon"></span>
  14 + </a>
  15 + </li>
  16 + </ul>
  17 +</nav>
... ...
src/app/components/app-paginator/app-paginator.scss 0 → 100644
... ... @@ -0,0 +1,40 @@
  1 +.app-paginator {
  2 + text-align: center;
  3 +
  4 + .btn-pagination {
  5 + background-color: transparent;
  6 + border: none;
  7 + border-radius: 100%;
  8 + font-weight: bold;
  9 + font-size: 20px;
  10 + padding: 0px 8px;
  11 + width: 28px;
  12 + height: 28px;
  13 + text-decoration: underline;
  14 + color: $defaultblue;
  15 + }
  16 +
  17 + .pagination-icon {
  18 + color: $defaultblue;
  19 + }
  20 +
  21 + .pagination > .active > a,
  22 + .pagination > .active > a:hover,
  23 + .pagination > .active > a:focus,
  24 + .pagination > .active > span,
  25 + .pagination > .active > span:hover,
  26 + .pagination > .active > span:focus {
  27 + background-color: $defaultblue;
  28 + text-decoration: none;
  29 +
  30 + }
  31 +
  32 + .pagination > .disabled > span,
  33 + .pagination > .disabled > span:hover,
  34 + .pagination > .disabled > span:focus,
  35 + .pagination > .disabled > a,
  36 + .pagination > .disabled > a:hover,
  37 + .pagination > .disabled > a:focus {
  38 + background-color: transparent;
  39 + }
  40 +}
... ...
src/app/components/article-service/article.service.js
... ... @@ -96,25 +96,11 @@
96 96 }
97 97  
98 98 function getProposals (params, cbSuccess, cbError) {
99   - // Ex.: /api/v1/articles/103358?fields=
100   -
101   - // var url = service.apiArticles + API.articleId.home;
102   -
103   - // var paramsExtended = angular.extend({
104   - // // 'fields[]': ['id', 'title', 'slug', 'abstract', 'categories', 'setting', 'children', 'children_count'],
105   - // 'content_type':'ProposalsDiscussionPlugin::Proposal'
106   - // }, params);
107   -
108   - // UtilService.get(url, {params: paramsExtended}).then(function(data){
109   - // cbSuccess(data);
110   - // }).catch(function(error){
111   - // cbError(error);
112   - // });
113   -
114   - //
115   - searchProposals({
  99 + var paramsExtended = angular.extend({
116 100 query: ''
117   - }, cbSuccess, cbError);
  101 + }, params);
  102 +
  103 + searchProposals(paramsExtended, cbSuccess, cbError);
118 104 }
119 105  
120 106 function getProposalById (proposalId, params, cbSuccess, cbError) {
... ... @@ -257,8 +243,9 @@
257 243 // Ex.: /api/v1/search/article?type=ProposalsDiscussionPlugin::Proposal&query=cisternas
258 244 var url = '/api/v1/search/article';
259 245 var paramsExtended = angular.extend({
260   - // 'fields[]': ['id', 'title', 'slug', 'abstract', 'categories', 'setting', 'children_count', 'hits'],
261   - 'type': 'ProposalsDiscussionPlugin::Proposal'
  246 + page: 1,
  247 + per_page: 20,
  248 + type: 'ProposalsDiscussionPlugin::Proposal'
262 249 }, params);
263 250  
264 251 UtilService.get(url, {params: paramsExtended}).then(function(data){
... ...
src/app/components/auth-user/auth-user.html
1 1 <div class="auth-user">
2 2 <div ng-if="vm.currentUser" class="pull-right">
3   - <span>{{::vm.currentUser.login}}</span>
  3 + <span ng-if="vm.currentUser.person">{{::vm.currentUser.person.name}}</span>
  4 + <span ng-if="!vm.currentUser.person">{{::vm.currentUser.login}}</span>
4 5 <span>|</span>
5 6 <button type="button" class="btn btn-link" ng-click="vm.onClickLogout()">Sair</button>
6 7 </div>
7 8  
8 9 <div ng-if="!vm.currentUser">
9   - <button type="button" class="btn btn-link pull-right" ui-sref="entrar">
10   - <!-- <span class="icon icon-user" aria-hidden="true"></span> -->
11   - <!-- <span class="glyphicon glyphicon-user"></span> -->
12   - Entrar
13   - </button>
  10 + <button type="button" class="btn btn-link pull-right" ui-sref="entrar">Entrar</button>
14 11 </div>
15 12 </div>
... ...
src/app/components/auth/auth.service.js
... ... @@ -39,6 +39,7 @@
39 39  
40 40 var currentUser = Session.create(response.data);
41 41  
  42 + $rootScope.currentUser = currentUser;
42 43 $rootScope.$broadcast(AUTH_EVENTS.registerSuccess, currentUser);
43 44 $rootScope.$broadcast(AUTH_EVENTS.loginSuccess, currentUser);
44 45  
... ... @@ -101,10 +102,13 @@
101 102 });
102 103 }
103 104  
104   - function forgotPassword (form){
105   - var url = '/api/v1/forgot_password';
106   - var data = form.serialize();
107   - var encodedData = data;
  105 + function forgotPassword (data){
  106 + var url = 'http://hom.login.dialoga.gov.br/api/v1/forgot_password';
  107 + var encodedData = ([
  108 + 'value=' + data.login,
  109 + 'captcha_text=' + data.captcha_text,
  110 + 'txtToken_captcha_serpro_gov_br=' + data.txtToken_captcha_serpro_gov_br
  111 + ]).join('&');
108 112  
109 113 return $http
110 114 .post(url, encodedData)
... ... @@ -113,11 +117,14 @@
113 117  
114 118 // 'Verifique seu email para efetuar a troca da senha.'
115 119 $rootScope.$broadcast(AUTH_EVENTS.forgotPasswordSuccess, response);
  120 +
116 121 return response;
117 122 }, function(response) {
118 123 // 'Não foi possível requisitar a troca de senha para os dados informados.'
119 124 $log.debug('AuthService.forgotPassword [FAIL] response', response);
120 125 $rootScope.$broadcast(AUTH_EVENTS.forgotPasswordFailed);
  126 +
  127 + return response;
121 128 });
122 129 }
123 130  
... ...
src/app/components/category-list/category-list.directive.js
... ... @@ -32,6 +32,17 @@
32 32 }
33 33 };
34 34  
  35 + CategoryListController.prototype._disableUnselect = function() {
  36 + var vm = this;
  37 +
  38 + if(vm.disableUnselect && vm.disableUnselect === 'true'){
  39 + return true;
  40 + }
  41 +
  42 + return false;
  43 + };
  44 +
  45 +
35 46 CategoryListController.prototype.selectCategory = function(category, $event) {
36 47 var vm = this;
37 48  
... ... @@ -39,9 +50,14 @@
39 50 $event.stopPropagation();
40 51  
41 52 if (category !== vm.selectedCategory) {
42   - // selected new filter
43 53 vm.selectedCategory = category;
44   - } else {
  54 + }else{
  55 +
  56 + if(vm._disableUnselect()){
  57 + vm.$log.info('Unselect is disabled.');
  58 + return;
  59 + }
  60 +
45 61 vm.selectedCategory = null;
46 62 }
47 63  
... ... @@ -65,7 +81,8 @@
65 81 templateUrl: 'app/components/category-list/category-list.html',
66 82 scope: {
67 83 categories: '=',
68   - selectedCategory: '='
  84 + selectedCategory: '=',
  85 + disableUnselect: '@'
69 86 },
70 87 controller: CategoryListController,
71 88 controllerAs: 'vm',
... ...
src/app/components/category-list/category-list.html
... ... @@ -13,7 +13,7 @@
13 13 ng-click="vm.selectCategory(category, $event)">
14 14  
15 15 <span class="category-list--icon-circle" aria-hidden="true" ng-class="category.slug"></span>
16   - <span class="category-list--icon icon" aria-hidden="true" ng-class="'icon-tema-' + category.slug"></span>
  16 + <span class="category-list--icon icon" aria-hidden="true" ng-class="'icon-tema-' + category.slug + '-small'"></span>
17 17 <span class="category-list--label">{{::category.name}}</span>
18 18 <span class="category-list--icon--right glyphicon glyphicon-chevron-right hidden-xs" ng-hide="vm.selectedCategory.slug === category.slug"></span>
19 19 <span class="category-list--icon--right glyphicon glyphicon-remove hidden-xs" ng-show="vm.selectedCategory.slug === category.slug"></span>
... ...
src/app/components/category-list/category-list.scss
... ... @@ -79,9 +79,9 @@
79 79  
80 80 .category-list--icon {
81 81 position: absolute;
82   - top: -16px;
83   - left: -14px;
84   - transform: scale(0.35);
  82 + top: 6px;
  83 + left: 6px;
  84 + // transform: scale(0.4);
85 85 }
86 86  
87 87 .category-list--icon--right {
... ...
src/app/components/dialoga-service/dialoga.service.js
... ... @@ -19,6 +19,7 @@
19 19 extendedService.getThemeBySlug = getThemeBySlug;
20 20 extendedService.getPrograms = getPrograms;
21 21 extendedService.getProgramBySlug = getProgramBySlug;
  22 + extendedService.getProgramsByThemeId = getProgramsByThemeId;
22 23 extendedService.getProgramsRandom = getProgramsRandom;
23 24 extendedService.getEvents = getEvents; // override
24 25 extendedService.getQuestions = getQuestions;
... ... @@ -89,6 +90,7 @@
89 90 },cbError);
90 91 }
91 92 }
  93 +
92 94 function getThemeBySlug (slug, cbSuccess, cbError) {
93 95 if( !!CACHE.themes ){
94 96 _getThemeBySlug(CACHE.themes);
... ... @@ -146,6 +148,28 @@
146 148 }
147 149 }
148 150  
  151 + function getProgramsByThemeId (themeId, cbSuccess, cbError) {
  152 +
  153 + if( !CACHE.programs ){
  154 + getPrograms(_getProgramsByThemeId, cbError);
  155 + } else {
  156 + _getProgramsByThemeId();
  157 + }
  158 +
  159 + function _getProgramsByThemeId(){
  160 + var result = CACHE.programs.filter(function filterProgramBySlug (program) {
  161 + var category = program.categories[0];
  162 +
  163 + if(category && angular.equals(category.id, themeId)) {
  164 + return true;
  165 + }
  166 + return false;
  167 + });
  168 +
  169 + cbSuccess(result);
  170 + }
  171 + }
  172 +
149 173 // Ex.: /api/v1/dialoga_plugin/random_topics/103358
150 174 // TODO: get endpoint for production
151 175 // TODO: put at cache?
... ... @@ -202,8 +226,8 @@
202 226 ArticleService.searchTopics({query: query}, cbSuccess, cbError);
203 227 }
204 228  
205   - function searchProposals (query, cbSuccess, cbError) {
206   - ArticleService.searchProposals({query: query}, cbSuccess, cbError);
  229 + function searchProposals (params, cbSuccess, cbError) {
  230 + ArticleService.searchProposals(params, cbSuccess, cbError);
207 231 }
208 232  
209 233 function _pipeHandleYoutube (data) {
... ...
src/app/components/event-list/event-list.directive.js
... ... @@ -40,13 +40,19 @@
40 40 vm.isCollapsed = !vm.isCollapsed;
41 41 };
42 42  
43   - EventListController.prototype.subscribe = function (event_id) {
  43 + EventListController.prototype.subscribe = function (event) {
44 44 var vm = this;
45 45  
  46 + if(event.isOld){
  47 + vm.$log.debug('Event already happened. Abort.');
  48 + return;
  49 + }
  50 +
  51 + var event_id = event.id;
46 52 vm.$log.debug('event_id', event_id);
47 53  
48 54 if(!vm.$rootScope.currentUser){
49   - vm.$log.warn('User is not logged in. Redirect to Auth page.');
  55 + vm.$log.info('User is not logged in. Redirect to Auth page.');
50 56 vm.$state.go('entrar',{
51 57 redirect_uri: 'state=inicio&task=subscribe&event_id=' + event_id
52 58 },{
... ...
src/app/components/event-list/event-list.html
... ... @@ -11,10 +11,11 @@
11 11 Agenda <b>Dialoga Brasil</b>
12 12 </h1>
13 13 </div>
14   - <div class="col-sm-6">
  14 + <div class="col-sm-6 text-right">
15 15 <h2 class="event-bar--trigger-toggle text-right">
16   - <span><b>18</b> bate papos <b>agendados</b></span>
17   - <span class="glyphicon glyphicon-menu-down" aria-hidden="true"></span>
  16 + <span><b>{{vm.events.length}}</b> bate papos <b>agendados</b></span>
  17 + <span ng-if="vm.isCollapsed" class="glyphicon glyphicon-menu-down" aria-hidden="true"></span>
  18 + <span ng-if="!vm.isCollapsed" class="glyphicon glyphicon-menu-up" aria-hidden="true"></span>
18 19 </h2>
19 20 </div>
20 21 </div>
... ... @@ -25,46 +26,36 @@
25 26  
26 27 <section class="section-table">
27 28 <div class="container">
28   - <!-- <div class="event-tab--trigger" ng-show="vm.isCollapsed" ng-click="vm.toggleView()">
29   - <div class="event-tab--header">
30   - <div class="event-tab--icon">
31   - <span class="glyphicon glyphicon-calendar" aria-hidden="true"></span>
32   - </div>
33   - <div class="event-tab--title">Bate-Papo com ministr@s</div>
34   - </div>
35   - <button class="btn btn-link event-tab--button">
36   - <span class="event-tab--total-scheduled">18</span>
37   - <span>bate-papos agendados</span>
38   - <span class="glyphicon glyphicon-triangle-bottom" aria-hidden="true"></span>
39   - </button>
40   - </div> -->
41   -
42 29 <div class="event-list--panel ng-hide" ng-show="!vm.isCollapsed">
43 30 <div class="event-list--table-wrapper">
44 31 <div class="row row-level-1" ng-repeat="event in vm.events | orderBy:'start_date':false">
45   - <div class="col-xs-12 col-sm-4 col-md-6 vcenter">
46   - <span class="glyphicon glyphicon-calendar"></span>
47   - <span class="date">{{event.start_date | date : "dd/MM/yyyy"}}</span>
48   - <span class="separator">-</span>
49   - <span class="glyphicon glyphicon-time"></span>
50   - <span class="time">{{event.start_date | date : "HH:mm"}}</span>
51   - <span class="separator">-</span>
52   - <span class="description">{{::event.title}}</span>
  32 + <div class="col-xs-12 col-sm-4 col-md-3 vcenter">
  33 + <span class="date-wrapper">
  34 + <span class="glyphicon glyphicon-calendar"></span>
  35 + <span class="date">{{event.start_date | date : "dd/MM/yyyy"}}</span>
  36 + </span>
  37 + <span class="time-wrapper">
  38 + <span class="glyphicon glyphicon-time"></span>
  39 + <span class="time">{{event.start_date | date : "HH:mm"}}</span>
  40 + </span>
53 41 </div>
54   - <div class="col-xs-12 col-sm-4 col-md-3 text-center vcenter">
55   - <span class="theme">{{::event.categories[0].name}}</span>
  42 + <div class="col-xs-12 col-sm-4 col-md-5 vcenter">
  43 + <span class="description">{{::event.title.split('-')[0]}}</span>
56 44 </div>
57   - <div class="col-xs-12 col-sm-4 col-md-3 text-right vcenter" style="padding-right: 20px;">
  45 + <!-- <div class="col-xs-12 col-sm-4 col-md-3 text-center vcenter">
  46 + <span class="theme">{{::event.categories[0].name}}</span>
  47 + </div> -->
  48 + <div class="col-xs-12 col-sm-4 col-md-4 text-right vcenter" style="padding-right: 20px;">
58 49 <div class="row">
59   - <div class="col-xs-6 text-right" ng-class="{'col-xs-12': event.isOld}">
  50 + <div class="col-xs-6 text-right">
60 51 <div ng-if="event.followers_count > 50">
61 52 <b>{{::event.followers_count}}</b>
62 53 <br/>
63 54 <span>Inscritos</span>
64 55 </div>
65 56 </div>
66   - <div class="col-xs-6" ng-if="!event.isOld">
67   - <button type="button" class="btn color-theme-common-bg" ng-click="vm.subscribe(event.id)">
  57 + <div class="col-xs-6">
  58 + <button type="button" class="btn color-theme-common-bg btn-disabled" disabled ng-click="vm.subscribe(event)">
68 59 Inscreva-se
69 60 <span class="sr-only">no bate-papo com (ministro) no dia {event.start_date | date : "dd/MM/yyyy"}} as {{event.start_date | date : "HH:mm"}} horas</span>
70 61 </button>
... ... @@ -75,5 +66,17 @@
75 66 </div>
76 67 </div>
77 68 </div>
  69 + <div class="container visible-xs" ng-show="!vm.isCollapsed">
  70 + <div class="minimize" ng-click="vm.toggleView()">
  71 + <div class="row color-theme-common-bg">
  72 + <div class="col-xs-6">
  73 + <button type="button" class="btn btn-link" ng-click="">MINIMIZAR</button>
  74 + </div>
  75 + <div class="col-xs-5 text-right">
  76 + <span class="glyphicon glyphicon-menu-up" aria-hidden="true"></span>
  77 + </div>
  78 + </div>
  79 + </div>
  80 + </div>
78 81 </section>
79 82 </div>
... ...
src/app/components/event-list/event-list.scss
... ... @@ -10,37 +10,41 @@
10 10 }
11 11  
12 12 .event-list--panel {
13   - height: 310px;
14   - padding: 0px;
15   - margin: 20px 0;
16   - line-height: 20px;
  13 + width: 100%;
  14 + height: 240px;
  15 + margin: 8px 0;
  16 + padding: 0 20px;
  17 + overflow-x: hidden;
  18 + overflow-y: scroll;
17 19 transition: .3s linear all;
18   - overflow: hidden;
19 20  
20 21 &.ng-hide {
21 22 height: 0;
22 23 line-height: 0;
23 24 }
24 25  
25   - // .event-list--header {
26   - // border-bottom: 1px solid #333333;
27   - // }
28   -
29   - // .event-list--icon {
30   - // font-size: 25px;
31   - // display: inline-block;
32   - // }
33   -
34   - // .event-list--title {
35   - // margin: 0 10px;
36   - // display: inline-block;
37   - // }
38   -
39   - // .event-list--minimize {
40   - // display: inline-block;
41   - // float: right;
42   - // width: 100px;
43   - // }
  26 + .btn {
  27 + color: #e1e1e1;
  28 + text-transform: uppercase;
  29 + font-weight: bold;
  30 + }
  31 +
  32 + .row-level-1 {
  33 + // height: 48px;
  34 + line-height: 20px;
  35 + padding: 5px 0;
  36 + border-bottom: 1px solid #ccc;
  37 + }
  38 +
  39 + .row-level-1:last-child {
  40 + border-bottom: none;
  41 + }
  42 +
  43 +
  44 + @media screen and (max-width: $screen-sm) {
  45 + height: auto;
  46 + overflow: visible;
  47 + }
44 48 }
45 49  
46 50 &--table{
... ... @@ -61,10 +65,7 @@
61 65 line-height: 20px;
62 66 cursor: pointer;
63 67  
64   - -webkit-transition: -webkit-transform 0.3s linear all;
65   - -moz-transition: -moz-transform 0.3s linear all;
66   - -o-transition: -o-transform 0.3s linear all;
67   - transition: transform 0.3s linear all;
  68 + transition: all 0.3s linear all;
68 69  
69 70 overflow: hidden;
70 71 z-index: 100;
... ... @@ -90,38 +91,29 @@
90 91  
91 92 .icon-circle {
92 93 font-size: 28px;
  94 + line-height: 33px;
93 95 border-radius: 100%;
94 96 padding: 8px 8px 8px 10px;
95 97 background-color: #fff;
96 98 }
97 99  
98 100 &-toggle {
  101 + display: inline-block;
  102 + text-transform: uppercase;
  103 + font-size: 16px;
  104 +
99 105 .glyphicon {
100 106 position: relative;
101 107 top: 5px;
  108 + font-size: 30px;
102 109 }
103 110 }
104 111 }
105 112  
106 113 .event-list--panel {
107   - width: 100%;
108   - height: 260px;
109   - overflow-y: scroll;
110   -
111   - .btn {
112   - color: #e1e1e1;
113   - text-transform: uppercase;
114   - font-weight: bold;
115   - }
116   -
117   - .row-level-1 {
118   - padding: 5px 0;
119   - border-top: 1px solid #ccc;
120   - }
121   -
122   - .row-level-1:last-child {
123   - border-bottom: 1px solid #ccc;
124   - }
  114 + .date-wrapper {margin-left: 16px; }
  115 + .time-wrapper {margin-left: 22px; }
  116 + // .description {margin-left: 22px; }
125 117 }
126 118  
127 119 .event-tab--icon {
... ... @@ -139,4 +131,18 @@
139 131 width: 100%;
140 132 white-space: normal;
141 133 }
  134 +
  135 + .minimize {
  136 + cursor: pointer;
  137 +
  138 + .btn,
  139 + .glyphicon {
  140 + color: #fff;
  141 + font-weight: bold;
  142 + }
  143 +
  144 + .glyphicon {
  145 + line-height: 32px;
  146 + }
  147 + }
142 148 }
... ...
src/app/components/navbar/navbar.html
1 1 <div class="app-navbar">
2   - <div id="dialoga-nas-redes">
3   - <div class="text text-right">
4   - <p>Dialoga<br>Nas Redes</p>
5   - </div>
6   - <social-share></social-share>
7   - </div>
8 2 <nav id="navigation" class="header-navbar navbar navbar-static-top" role="navigation">
9 3 <div class="navbar-header">
10 4 <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse" aria-expanded="false">
... ... @@ -15,7 +9,6 @@
15 9 </button>
16 10 <a class="navbar-brand" ui-sref="inicio">
17 11 <img src="/assets/images/logo.png" alt="Dialoga Brasil | O país fica melhor quando você participa" />
18   - <!-- <span class="glyphicon glyphicon-home"></span> Início -->
19 12 </a>
20 13 </div>
21 14  
... ... @@ -29,48 +22,41 @@
29 22 <li role="separator" class="divider hidden-xs hidden-sm"><span>|</span></li>
30 23 <li class="dropdown">
31 24 <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>
32   - <social-share class="dropdown-menu dropdown-menu-right"></social-share>
33   - <!-- <ul class="dropdown-menu dropdown-menu-right dropdown-menu-social">
34   - <li>
35   - <a socialshare
36   - socialshare-provider="facebook"
37   - socialshare-url="http://dialoga.gov.br"
38   - socialshare-text="Conheça o Dialoga Brasil. Dialoga Brasil | O País fica melhor quando VOCÊ PARTICIPA."
39   - title="Compartilhar no Facebook">
40   - <span class="icon-circle icon-small icon-circle-social-facebook"><span class="icon icon-social-facebook"></span></span>
41   - <span class="sr-only">Compartilhar no Facebook</span>
42   - </a>
43   - </li>
44   - <li>
45   - <a socialshare
46   - socialshare-provider="twitter"
47   - socialshare-url="http://dialoga.gov.br"
48   - socialshare-text="Conheça o Dialoga Brasil. Dialoga Brasil | O País fica melhor quando VOCÊ PARTICIPA."
49   - socialshare-hastags="dialogabrasil"
50   - title="Compartilhar no Twitter">
51   - <span class="icon-circle icon-small icon-circle-social-twitter"><span class="icon icon-social-twitter"></span></span>
52   - <span class="sr-only">Compartilhar no Twitter</span>
53   - </a>
54   - </li>
55   - <li>
56   - <a socialshare
57   - socialshare-provider="gplus"
58   - socialshare-url="http://dialoga.gov.br"
59   - socialshare-text="Conheça o Dialoga Brasil. Dialoga Brasil | O País fica melhor quando VOCÊ PARTICIPA."
60   - title="Compartilhar no Google Plus">
61   - <span class="icon-circle icon-small icon-circle-social-googleplus"><span class="icon icon-social-googleplus"></span></span>
62   - <span class="sr-only">Compartilhar no Google Plus</span>
63   - </a>
64   - </li>
65   - <li>
66   - <a href="mailto:contato@dialoga.gov.br?subject=Conheça o Dialoga Brasil" title="Enviar por email">
67   - <span class="icon-circle icon-small icon-circle-social-whatsapp"><span class="icon icon-social-whatsapp"></span></span>
68   - <span class="sr-only">Enviar por email</span>
69   - </a>
70   - </li>
71   - </ul> -->
  25 + <social-share class="dropdown-menu dropdown-menu-right" arrow-class="social-share--arrow"></social-share>
72 26 </li>
73 27 </ul>
74 28 </div>
75 29 </nav>
  30 +
  31 + <div id="dialoga-nas-redes">
  32 + <div class="text text-right">
  33 + <p>DIALOGA<br><b>NAS REDES</b></p>
  34 + </div>
  35 + <ul class="social-share list-inline">
  36 + <li>
  37 + <a href="https://www.facebook.com/DialogaBrasil" target="_blank">
  38 + <span aria-hidden="true" class="icon-circle icon-small icon-circle-social-facebook"><span class="icon icon-social-facebook"></span></span>
  39 + <span class="sr-only">Visitar perfil no Facebook</span>
  40 + </a>
  41 + </li>
  42 + <li>
  43 + <a href="https://twitter.com/dialogabrasil" target="_blank">
  44 + <span aria-hidden="true" class="icon-circle icon-small icon-circle-social-twitter"><span class="icon icon-social-twitter"></span></span>
  45 + <span class="sr-only">Visitar perfil no Twitter</span>
  46 + </a>
  47 + </li>
  48 + <li>
  49 + <a href="https://www.youtube.com/channel/UCtjaJwOWwGu2legqFVAzhIA" target="_blank">
  50 + <span aria-hidden="true" class="icon-circle icon-small icon-circle-social-youtube"><span class="icon icon-social-youtube"></span></span>
  51 + <span class="sr-only">Visitar canal no Youtube</span>
  52 + </a>
  53 + </li>
  54 + <li>
  55 + <a href="https://www.flickr.com/photos/dialogabrasil" target="_blank">
  56 + <span aria-hidden="true" class="icon-circle icon-small icon-circle-social-flickr"><span class="icon icon-social-flickr"></span></span>
  57 + <span class="sr-only">Visitar canal no Flickr</span>
  58 + </a>
  59 + </li>
  60 + </ul>
  61 + </div>
76 62 </div>
... ...
src/app/components/proposal-box/proposal-box.directive.js
... ... @@ -34,6 +34,10 @@
34 34 vm.errorOnSkip = false;
35 35 vm.showAuthMessage = null;
36 36 vm.voteProposalRedirectURI = null;
  37 +
  38 + var slug = vm.topic.slug;
  39 + var proposal_id = vm.proposal.id;
  40 + vm.voteProposalRedirectURI = 'state=programa&task=vote-proposal&slug=' + slug + '&proposal_id=' + proposal_id;
37 41 };
38 42  
39 43 ProposalBoxController.prototype.addListeners = function () {
... ... @@ -64,14 +68,6 @@
64 68  
65 69 vm.message = data.message;
66 70 });
67   -
68   - vm.$scope.$watch('vm.voteProposalRedirectURI', function(newValue, oldValue){
69   - if(newValue && newValue !== oldValue){
70   - var slug = vm.topic.slug;
71   - var proposal_id = vm.proposal.id;
72   - vm.voteProposalRedirectURI = 'state=programa&task=vote-proposal&slug=' + slug + '&proposal_id=' + proposal_id;
73   - }
74   - });
75 71 };
76 72  
77 73 ProposalBoxController.prototype.showContent = function (slug) {
... ...
src/app/components/proposal-box/proposal-box.html
... ... @@ -75,7 +75,6 @@
75 75 <p>Você precisa estar logado para votar na proposta</p>
76 76 <br>
77 77 <p>
78   - <!-- <a ui-sref="entrar({redirect_uri: vm.voteProposalRedirectURI})">Clique aqui</a> para ir para a página de login. -->
79 78 <a ui-sref="entrar({redirect_uri: vm.voteProposalRedirectURI})">Clique aqui para ir para a página de login</a>
80 79 </p>
81 80 </div>
... ... @@ -95,9 +94,8 @@
95 94 <div ng-show="!vm.errorOnSkip">
96 95 <p>Carregando...</p>
97 96 </div>
98   - <div ng-show="!vm.errorOnSkip">
  97 + <div ng-show="vm.errorOnSkip">
99 98 <p>Erro ao carregar nova proposta proposta.</p>
100   - <p>{{vm.errorOnSkip}}</p>
101 99 </div>
102 100 </div>
103 101 </div>
... ... @@ -117,7 +115,6 @@
117 115 <div ng-hide="vm.canVote" class="proposal-box--join">
118 116 <button class="btn btn-link color-theme-common-fg" ng-click="vm.showContent(vm.topic.slug)">
119 117 Participe
120   - <span class="glyphicon glyphicon-menu-right color-theme-common-fg" aria-hidde="true"></span>
121 118 </button>
122 119 </div>
123 120 <div ng-show="vm.canVote" class="proposal-box--actions text-center">
... ...
src/app/components/proposal-box/proposal-box.scss
... ... @@ -69,6 +69,7 @@
69 69 .proposal-box--join {
70 70 .btn {
71 71 font-weight: bold;
  72 + padding: 6px 0;
72 73 }
73 74 }
74 75  
... ...
src/app/components/proposal-carousel/proposal-carousel.directive.js
... ... @@ -9,11 +9,12 @@
9 9 function proposalCarousel() {
10 10  
11 11 /** @ngInject */
12   - function ProposalCarouselController($scope, $element, $timeout, $log) {
  12 + function ProposalCarouselController($scope, $state, $element, $timeout, $log) {
13 13 $log.debug('ProposalCarouselController');
14 14  
15 15 var vm = this;
16 16 vm.$scope = $scope;
  17 + vm.$state = $state;
17 18 vm.$element = $element;
18 19 vm.$timeout = $timeout;
19 20 vm.$log = $log;
... ... @@ -63,6 +64,18 @@
63 64 vm.$scope.$emit('proposal-carousel:showProposalsList');
64 65 };
65 66  
  67 + ProposalCarouselController.prototype.showContent = function (proposal) {
  68 + var vm = this;
  69 +
  70 + vm.$state.go('programa', {
  71 + slug: proposal.parent.slug,
  72 + proposal_id: proposal.id
  73 + }, {
  74 + location: true,
  75 + reload: true
  76 + });
  77 + };
  78 +
66 79 var directive = {
67 80 restrict: 'E',
68 81 templateUrl: 'app/components/proposal-carousel/proposal-carousel.html',
... ...
src/app/components/proposal-carousel/proposal-carousel.html
... ... @@ -16,7 +16,15 @@
16 16 <div class="proposal-carousel-middle" ng-swipe-left="vm.swipeLeft()" ng-swipe-right="vm.swipeRight()">
17 17 <div ng-repeat="proposal in vm.proposals" class="animation-swipe">
18 18 <div class="content">
19   - <div ng-show="vm.activeIndex === $index">{{::proposal.abstract}}</div>
  19 + <div ng-show="vm.activeIndex === $index">
  20 + <div class="inner">{{::proposal.abstract}}</div>
  21 + </div>
  22 + </div>
  23 + <div class="join" ng-show="vm.activeIndex === $index">
  24 + <button type="button" class="btn btn-link btn-rate color-theme-common-fg" ng-click="vm.showContent(proposal)">
  25 + Participe
  26 + <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
  27 + </button>
20 28 </div>
21 29 <div class="proposal-carousel-middle-watermark" ng-show="vm.activeIndex === $index">
22 30 <span>{{::($index+1)}}º</span>
... ... @@ -26,7 +34,7 @@
26 34 <div class="proposal-carousel-bottom color-theme-common-bg" ng-click="vm.showProposalsList()">
27 35 <div>Veja as propostas mais votadas</div>
28 36 <div class="proposal-carousel-bottom-icon">
29   - <span class="glyphicon glyphicon-chevron-down pull-right color-theme-common-fg"></span>
  37 + <span class="glyphicon glyphicon-chevron-down pull-right color-theme-common-fg" aria-hidden="true"></span>
30 38 </div>
31 39 </div>
32 40 </div>
... ...
src/app/components/proposal-carousel/proposal-carousel.scss
... ... @@ -9,12 +9,12 @@
9 9 color: #fff;
10 10 font-weight: bold;
11 11 font-size: 25px;
12   - padding: 20px 15px;
  12 + padding: 10px 15px;
13 13  
14 14 &-triggers {
15 15 position: absolute;
16 16 right: 15px;
17   - top: 20px;
  17 + top: 8px;
18 18  
19 19 button {
20 20 border: 1px solid #fff;
... ... @@ -46,14 +46,26 @@
46 46  
47 47 .content {
48 48 position: relative;
49   - z-index: 2;
  49 + z-index: 10;
  50 + }
  51 +
  52 + .join {
  53 + position: absolute;
  54 + bottom: 32px;
  55 + z-index: 10;
  56 +
  57 + .btn {
  58 + padding: 0;
  59 + font-weight: bold;
  60 + font-size: 16px;
  61 + }
50 62 }
51 63  
52 64 &-watermark {
53 65 position: absolute;
54 66 bottom: 1px;
55 67 left: -5px;
56   - color: #ddd;
  68 + color: #e6e6e6;
57 69 font-size: 150px;
58 70 font-weight: bold;
59 71 line-height: 116px;
... ...
src/app/components/proposal-list/proposal-list.directive.js
... ... @@ -9,20 +9,16 @@
9 9 function proposalList() {
10 10  
11 11 /** @ngInject */
12   - function ProposalListController(ArticleService, $state, $scope, $element, $timeout, $log) {
  12 + function ProposalListController($state, $element, $timeout, $log) {
13 13 $log.debug('ProposalListController');
14 14  
15 15 var vm = this;
16   - vm.ArticleService = ArticleService;
17 16 vm.$state = $state;
18   - vm.$scope = $scope;
19 17 vm.$element = $element;
20 18 vm.$timeout = $timeout;
21 19 vm.$log = $log;
22 20  
23 21 vm.init();
24   - vm.loadData();
25   - vm.attachListeners();
26 22 }
27 23  
28 24 ProposalListController.prototype.init = function () {
... ... @@ -33,75 +29,11 @@
33 29 throw { name: 'NotDefined', message: 'The attribute "proposals" is undefined.'};
34 30 }
35 31  
36   - if(!vm.perPage){
37   - vm.perPage = 5;
38   - }
39   -
40   - vm.initPorposalList();
41   - };
42   -
43   - ProposalListController.prototype.initPorposalList = function () {
44   - var vm = this;
45   -
46   - vm.currentPageIndex = 0;
47   -
48   - vm.proposalsPerPage = vm.getProposalsPerPage(0);
49   -
50   - vm.proposalsLength = vm.proposals.length;
51   -
52   -
53   - if ((vm.proposalsLength % vm.perPage) === 0) {
54   - vm.pages = vm.proposalsLength / vm.perPage;
55   - } else{
56   - vm.pages = (vm.proposalsLength / vm.perPage) + 1;
57   - }
58   -
59   - // vm.arraypages = new Array(Math.ceil(vm.pages));
60   - vm.arraypages = new Array(Math.floor(vm.pages));
61   - };
62   -
63   - ProposalListController.prototype.loadData = function () {
64   - // async values
65   - var vm = this;
66   -
67   - // requeue to wait until DOM be created
68 32 vm.$timeout(function(){
69 33 attachPopover.call(vm);
70 34 }, 1000);
71 35 };
72 36  
73   - ProposalListController.prototype.attachListeners = function () {
74   - var vm = this;
75   -
76   - vm.$scope.$watch('vm.proposals', function(/*newValue, oldValue*/) {
77   - vm.initPorposalList();
78   - });
79   - };
80   -
81   - ProposalListController.prototype.getProposalsPerPage = function (pageIndex) {
82   - var vm = this;
83   -
84   - var initialIndex = pageIndex * vm.perPage;
85   - var finalIndex = initialIndex + vm.perPage;
86   -
87   - return vm.proposals.slice(initialIndex, finalIndex);
88   - };
89   -
90   - ProposalListController.prototype.showPage = function (pageIndex) {
91   - var vm = this;
92   -
93   - if (pageIndex < 0) {
94   - pageIndex = 0;
95   - }
96   -
97   - if (pageIndex > (vm.arraypages.length-1)) {
98   - pageIndex = vm.arraypages.length-1;
99   - }
100   -
101   - vm.proposalsPerPage = vm.getProposalsPerPage(pageIndex);
102   - vm.currentPageIndex = pageIndex;
103   - };
104   -
105 37 ProposalListController.prototype.showContent = function (proposal) {
106 38 var vm = this;
107 39  
... ... @@ -131,8 +63,7 @@
131 63 restrict: 'E',
132 64 templateUrl: 'app/components/proposal-list/proposal-list.html',
133 65 scope: {
134   - proposals: '=',
135   - perPage: '='
  66 + proposals: '='
136 67 },
137 68 controller: ProposalListController,
138 69 controllerAs: 'vm',
... ...
src/app/components/proposal-list/proposal-list.html
1 1 <div class="proposal-list">
2   - <div class="" ng-if="vm.loading">
3   - <div class="">Carregando...</div>
4   - </div>
5   - <div class="" ng-if="!vm.loading && vm.proposalsPerPage">
  2 + <div class="" ng-if="vm.proposals">
6 3 <table class="table table-striped">
7 4 <thead>
8 5 <tr>
... ... @@ -14,7 +11,7 @@
14 11 </tr>
15 12 </thead>
16 13 <tbody>
17   - <tr ng-repeat="proposal in vm.proposalsPerPage">
  14 + <tr ng-repeat="proposal in vm.proposals">
18 15 <td class="color-theme-fg">
19 16 <span class="position">{{::proposal.ranking_position}}º</span>
20 17 </td>
... ... @@ -38,22 +35,5 @@
38 35 </tr>
39 36 </tbody>
40 37 </table>
41   - <nav ng-if="vm.arraypages.length > 1">
42   - <ul class="pagination">
43   - <li ng-style="{'visibility': (vm.currentPageIndex === 0) ? 'hidden' : 'visible'}">
44   - <a class="btn-pagination" href="#" aria-label="Previous" ng-click="vm.showPage(vm.currentPageIndex-1)">
45   - <span aria-hidden="true" class="glyphicon glyphicon-chevron-left pagination-icon"></span>
46   - </a>
47   - </li>
48   - <li ng-repeat="paginas in vm.arraypages track by $index" ng-class="{ 'active' : ($index) == vm.currentPageIndex }" >
49   - <a class="btn-pagination" href="#" ng-click="vm.showPage($index)">{{::($index)+1}}</a>
50   - </li>
51   - <li ng-style="{'visibility': (vm.currentPageIndex === (vm.arraypages.length -1)) ? 'hidden' : 'visible'}">
52   - <a class="btn-pagination" href="#" aria-label="Next" ng-click="vm.showPage(vm.currentPageIndex+1)">
53   - <span aria-hidden="true" class="glyphicon glyphicon-chevron-right pagination-icon"></span>
54   - </a>
55   - </li>
56   - </ul>
57   - </nav>
58 38 </div>
59 39 </div>
... ...
src/app/components/proposal-list/proposal-list.scss
... ... @@ -80,45 +80,4 @@
80 80 }
81 81 }
82 82  
83   - .btn-pagination {
84   - background-color: transparent;
85   - border: none;
86   - border-radius: 100%;
87   - font-weight: bold;
88   - font-size: 20px;
89   - padding: 0px 8px;
90   - width: 28px;
91   - height: 28px;
92   - text-decoration: underline;
93   - color: $defaultblue;
94   - }
95   -
96   - .pagination-icon {
97   - color: $defaultblue;
98   - }
99   -
100   - .pagination > .active > a,
101   - .pagination > .active > a:hover,
102   - .pagination > .active > a:focus,
103   - .pagination > .active > span,
104   - .pagination > .active > span:hover,
105   - .pagination > .active > span:focus {
106   - background-color: $defaultblue;
107   - text-decoration: none;
108   -
109   - }
110   -
111   - .pagination > .disabled > span,
112   - .pagination > .disabled > span:hover,
113   - .pagination > .disabled > span:focus,
114   - .pagination > .disabled > a,
115   - .pagination > .disabled > a:hover,
116   - .pagination > .disabled > a:focus {
117   - background-color: transparent;
118   - }
119   -
120   - nav {
121   - text-align: center;
122   - }
123   -
124 83 }
... ...
src/app/components/proposal-stats/proposal-stats.html
1 1 <div class="proposal-stats">
2 2 <ul class="list-inline">
3   - <li class="proposal-stats-views">
4   - <span class="glyphicon glyphicon-eye-open" aria-hidden="true"></span>
5   - <span>{{proposal.hits}}</span>
6   - </li>
7 3 <li class="proposal-stats-up">
8 4 <span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
9 5 <span>{{proposal.votes_for}}</span>
... ... @@ -12,5 +8,9 @@
12 8 <span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
13 9 <span>{{proposal.votes_against}}</span>
14 10 </li>
  11 + <li class="proposal-stats-views">
  12 + <span class="glyphicon glyphicon-eye-open" aria-hidden="true"></span>
  13 + <span>{{proposal.hits}}</span>
  14 + </li>
15 15 </ul>
16 16 </div>
... ...
src/app/components/social-share/social-share.directive.js
... ... @@ -14,6 +14,7 @@
14 14 url: '=',
15 15 image: '=',
16 16 text: '=',
  17 + arrowClass: '@',
17 18 },
18 19 controller: SocialShareController,
19 20 controllerAs: 'vm',
... ...
src/app/components/social-share/social-share.html
  1 +<div ng-if="vm.arrowClass">
  2 + <div ng-class="vm.arrowClass"></div>
  3 +</div>
1 4 <ul class="social-share list-inline">
2 5 <li>
  6 + <!-- socialshare-via="687948707977695" -->
3 7 <a href="#" role="button"
4 8 socialshare
5 9 socialshare-provider="facebook"
... ...
src/app/components/social-share/social-share.scss
1 1 .social-share {
2   - min-width: 200px;
  2 + min-width: 205px;
3 3 padding: 5px;
4   - height: 47px;
  4 + height: 50px;
5 5  
6 6 &:after {
7 7 clear: both;
... ... @@ -16,6 +16,7 @@
16 16 margin: 0;
17 17 width: 45px;
18 18 text-align: center;
  19 + transform: scale(0.9);
19 20  
20 21 & > a {
21 22 padding: 0;
... ... @@ -25,5 +26,46 @@
25 26 // margin-left: 5px;
26 27 }
27 28 }
  29 +
  30 + .dropdown-menu & {
  31 +
  32 + // .dropdown-menu .social-share
  33 + background-color: #E0E0E0;
  34 + border-radius: 5px;
  35 +
  36 + @media screen and (max-width: $screen-xs) {
  37 + background-color: #fff;
  38 + }
  39 +
  40 + li {
  41 + margin: 0 2px;
  42 +
  43 + &:first-child { margin-left: 0;}
  44 + &:last-child { margin-right: 0;}
  45 + }
  46 + }
28 47 }
29 48  
  49 +.social-share--arrow {
  50 + position: absolute;
  51 + width: 0;
  52 + height: 0;
  53 + border-color: transparent;
  54 + border-style: solid;
  55 +
  56 + .dropdown-menu-right & {
  57 + top: -10px;
  58 + right: 20px;
  59 + border-width: 0 10px 10px;
  60 + border-bottom-color: #E0E0E0;
  61 + }
  62 +
  63 + @media screen and (max-width: $screen-xs) {
  64 + display: none;
  65 + }
  66 +}
  67 +
  68 +.dropdown-menu {
  69 + box-shadow: none;
  70 + border: none;
  71 +}
... ...
src/app/components/topic-list/topic-list.directive.js
... ... @@ -31,7 +31,7 @@
31 31 var vm = this;
32 32  
33 33 if (!vm.article) {
34   - vm.$log.warn('no article to display. Tip: use a ng-if before use this directive');
  34 + vm.$log.debug('no article to display. Tip: use a ng-if before use this directive');
35 35 return;
36 36 }
37 37  
... ...
src/app/components/topics-select/topics-select.directive.js 0 → 100644
... ... @@ -0,0 +1,57 @@
  1 +(function() {
  2 + 'use strict';
  3 +
  4 + angular
  5 + .module('dialoga')
  6 + .directive('topicsSelect', topicsSelect);
  7 +
  8 + /** @ngInject */
  9 + function topicsSelect() {
  10 +
  11 + /** @ngInject */
  12 + function TopicsSelectController($rootScope, $log) {
  13 + $log.debug('TopicsSelectController');
  14 +
  15 + // alias
  16 + var vm = this;
  17 +
  18 + // dependencies
  19 + vm.$rootScope = $rootScope;
  20 + vm.$log = $log;
  21 +
  22 + // initialization
  23 + vm.init();
  24 + }
  25 +
  26 + TopicsSelectController.prototype.init = function() {
  27 + // var vm = this;
  28 + };
  29 +
  30 + TopicsSelectController.prototype.selectTopic = function() {
  31 + var vm = this;
  32 +
  33 + if (vm.selectedTopic === null) {
  34 + vm.$log.debug('Default topic selected.');
  35 + return;
  36 + }
  37 +
  38 + // send event to all controllers
  39 + vm.$rootScope.$broadcast('change-selectedTopic', vm.selectedTopic);
  40 + };
  41 +
  42 + var directive = {
  43 + restrict: 'E',
  44 + templateUrl: 'app/components/topics-select/topics-select.html',
  45 + scope: {
  46 + topics: '=',
  47 + selectedTopic: '='
  48 + },
  49 + controller: TopicsSelectController,
  50 + controllerAs: 'vm',
  51 + bindToController: true
  52 + };
  53 +
  54 + return directive;
  55 + }
  56 +
  57 +})();
... ...
src/app/components/topics-select/topics-select.html 0 → 100644
... ... @@ -0,0 +1,8 @@
  1 +<div class="topics-dropdown">
  2 + <select
  3 + ng-model="vm.selectedTopic"
  4 + ng-change="vm.selectTopic()"
  5 + ng-options="topic.title for topic in vm.topics track by topic.slug"
  6 + class="form-control">
  7 + </select>
  8 +</div>
... ...
src/app/components/util-service/utils.service.js
... ... @@ -48,6 +48,7 @@
48 48 */
49 49 function handleSuccess (response) {
50 50 $log.debug('[SUCCESS]', response);
  51 + response.data._obj = response;
51 52 return response.data;
52 53 }
53 54  
... ...
src/app/index.constants.js
... ... @@ -8,6 +8,10 @@
8 8 host: 'http://hom.dialoga.gov.br',
9 9 image: 'http://hom.login.dialoga.gov.br'
10 10 })
  11 + .constant('APP', {
  12 + facebook_app_id: '1',
  13 + google_app_id: '4',
  14 + })
11 15 .constant('API', {
12 16 token: null,
13 17 articleId: {
... ... @@ -33,15 +37,24 @@
33 37 notAuthorized: 'auth-not-authorized'
34 38 })
35 39 .constant('VOTE_STATUS', {
36   - SUCCESS: 0x1,
37   - ERROR: 0x10,
38   - LOADING: 0x100
  40 + SUCCESS: 1,
  41 + ERROR: 2,
  42 + LOADING: 4,
  43 + LOADED: 8
39 44 })
40 45 .constant('VOTE_OPTIONS', {
41 46 UP: 1,
42 47 DOWN: -1,
43 48 SKIP: 0
44 49 })
  50 + .constant('PROPOSAL_STATUS', {
  51 + SUCCESS: 1,
  52 + ERROR: 2,
  53 + LOADING: 4,
  54 + LOADED: 8,
  55 + SENDING: 16,
  56 + SENT: 32
  57 + })
45 58 .constant('USER_ROLES', {
46 59 all: '*',
47 60 admin: 'admin',
... ...
src/app/index.route.js
... ... @@ -33,7 +33,7 @@
33 33 })
34 34 .state('recuperar', {
35 35 url: '/recuperar',
36   - ncyBreadcrumb: {label: 'Recuperar'},
  36 + ncyBreadcrumb: {label: 'Recuperar senha'},
37 37 views: {
38 38 'main': {
39 39 templateUrl: 'app/pages/auth/recover.html',
... ... @@ -106,26 +106,12 @@
106 106 .state('ranking', {
107 107 url: '/ranking?tema&programa&filtro',
108 108 reloadOnSearch: false,
109   - ncyBreadcrumb: {label: 'Propostas'},
  109 + ncyBreadcrumb: {label: 'Ranking'},
110 110 views: {
111 111 'main': {
112   - templateUrl: 'app/pages/propostas/ranking.html',
113   - controller: 'PropostasPageController',
114   - controllerAs: 'pagePropostas'
115   - }
116   - }
117   - })
118   - .state('propostas-conteudo', {
119   - url: '/propostas/:id',
120   - ncyBreadcrumb: {
121   - label: '{{$parent.$root.contentTitle}}',
122   - parent: 'propostas'
123   - },
124   - views: {
125   - 'main': {
126   - templateUrl: 'app/pages/propostas/proposta.html',
127   - controller: 'PropostasPageController',
128   - controllerAs: 'pagePropostas'
  112 + templateUrl: 'app/pages/ranking/ranking.html',
  113 + controller: 'RankingPageController',
  114 + controllerAs: 'pageRanking'
129 115 }
130 116 }
131 117 })
... ... @@ -151,19 +137,7 @@
151 137 }
152 138 }
153 139 })
154   - .state('termos-de-uso', {
155   - url: '/termos-de-uso',
156   - ncyBreadcrumb: {label: 'Termos de Uso'},
157   - controller: 'ArticlePageController',
158   - views: {
159   - 'main': {
160   - templateUrl: 'app/pages/article/article.html',
161   - controller: 'ArticlePageController',
162   - controllerAs: 'pageArticle'
163   - }
164   - }
165   - })
166   - .state('mapa-do-site', {
  140 + .state('mapa-do-site', {
167 141 url: '/mapa-do-site',
168 142 ncyBreadcrumb: {label: 'Mapa do Site'},
169 143 views: {
... ...
src/app/index.run.js
... ... @@ -81,7 +81,7 @@
81 81 }
82 82  
83 83 /** @ngInject */
84   - function runSocialAuth($window, $rootScope, $interval, $log) {
  84 + function runSocialAuth($window, $rootScope, $interval) {
85 85  
86 86 $window.oauthClientAction = function(url) {
87 87 var child = $window.open(url, '_blank');
... ... @@ -103,7 +103,7 @@
103 103 };
104 104  
105 105 $window.addEventListener('message', function(eventMessage) {
106   - $log.debug('eventMessage', eventMessage);
  106 + // $log.debug('eventMessage', eventMessage);
107 107  
108 108 if (eventMessage.data.message === 'oauthClientPluginResult') {
109 109 $rootScope.$broadcast('oauthClientPluginResult', eventMessage);
... ... @@ -142,10 +142,10 @@
142 142  
143 143 if (mainContentArea) {
144 144 $timeout(function() {
145   - $rootScope.scrollTo(mainContentArea, $event);
  145 + $rootScope.scrollTo(angular.element(mainContentArea), $event);
146 146 }, 90); // force queue
147 147 } else {
148   - $log.warn('role="main" not found.');
  148 + $log.info('role="main" not found.');
149 149 }
150 150 };
151 151  
... ...
src/app/index.scss
... ... @@ -23,8 +23,42 @@ $defaultblue: #5E749D;
23 23 // -------------
24 24  
25 25 // 1.4 - dicionarios
26   -$categories: (saude: #3449b7, seguranca-publica: #e34748, educacao: #f39720, reducao-da-pobreza: #3ebb8f, cultura: #a63738);
27   -$categories-descriptions: (saude: "Saúde é direito de todos e dever do Estado. O Sistema Único de Saúde (SUS) é universal, integral e de responsabilidade do Governo Federal, estados e municípios. Atende a todos os brasileiros.", seguranca-publica: "A segurança pública é um direito fundamental dos cidadãos. A proteção da vida, a disseminação da cultura da paz e a integração dos órgãos e instituições municipais, estaduais e federais são os maiores compromissos dessa política pública.", educacao: "Uma pátria educadora se faz com oportunidades para todos. Nos últimos anos, o Brasil criou esse caminho de oportunidades. Ampliamos o acesso à educação em todos os níveis de ensino – da creche à pós-graduação – e para todos os brasileiros, independentemente de sua classe social. E ainda há muito a fazer. O Plano Nacional de Educação (PNE) estabelece novas metas para que o governo federal trabalhe em parceria com a sociedade, com os estados e os municípios na construção de um futuro melhor. Queremos agora um salto na qualidade do ensino.", reducao-da-pobreza: "Com o esforço do Brasil para reduzir a pobreza e a desigualdade, 36 milhões de pessoas superaram a miséria na última década e o país saiu do Mapa da Fome das Nações Unidas.", cultura: "O que nos singulariza no conjunto das nações é, em última instância, nossa cultura. É por ela que nos identificamos como brasileiros de norte a sul deste país. Uma grande nação precisa ter um desenvolvimento cultural à altura de sua grandeza, contemplando as dimensões simbólica, econômica e cidadã da cultura, que são parte central do projeto de um país democrático e plural. A pluralidade é nossa singularidade.");
  26 +$categories: (
  27 + saude: #3359a7,
  28 + seguranca-publica: #e95052,
  29 + educacao: #cc6cd9,
  30 + reducao-da-pobreza: #38c7a4,
  31 + cultura: #a63738,
  32 + esporte: #f15b31,
  33 + meio-ambiente: #3cc667
  34 +);
  35 +
  36 +$categories-complementary-1: (
  37 + saude: #4f8add,
  38 + seguranca-publica: #fb7c7f,
  39 + educacao: #ee9cff,
  40 + reducao-da-pobreza: #57e9cd,
  41 + cultura: #dc5557,
  42 + esporte: #fd8d4c,
  43 + meio-ambiente: #339950
  44 +);
  45 +
  46 +$categories-complementary-2: (
  47 + saude: #2a4781,
  48 + seguranca-publica: #c43e3e,
  49 + educacao: #93549e,
  50 + reducao-da-pobreza: #2a9677,
  51 + cultura: #862f2f,
  52 + esporte: #ce472c,
  53 + meio-ambiente: lighten(#3cc667, 10%)
  54 +);
  55 +
  56 +// $categories-descriptions: (
  57 +// saude: "Saúde é direito de todos e dever do Estado. O Sistema Único de Saúde (SUS) é universal, integral e de responsabilidade do Governo Federal, estados e municípios. Atende a todos os brasileiros.",
  58 +// seguranca-publica: "A segurança pública é um direito fundamental dos cidadãos. A proteção da vida, a disseminação da cultura da paz e a integração dos órgãos e instituições municipais, estaduais e federais são os maiores compromissos dessa política pública.",
  59 +// educacao: "Uma pátria educadora se faz com oportunidades para todos. Nos últimos anos, o Brasil criou esse caminho de oportunidades. Ampliamos o acesso à educação em todos os níveis de ensino – da creche à pós-graduação – e para todos os brasileiros, independentemente de sua classe social. E ainda há muito a fazer. O Plano Nacional de Educação (PNE) estabelece novas metas para que o governo federal trabalhe em parceria com a sociedade, com os estados e os municípios na construção de um futuro melhor. Queremos agora um salto na qualidade do ensino.",
  60 +// reducao-da-pobreza: "Com o esforço do Brasil para reduzir a pobreza e a desigualdade, 36 milhões de pessoas superaram a miséria na última década e o país saiu do Mapa da Fome das Nações Unidas.",
  61 +// cultura: "O que nos singulariza no conjunto das nações é, em última instância, nossa cultura. É por ela que nos identificamos como brasileiros de norte a sul deste país. Uma grande nação precisa ter um desenvolvimento cultural à altura de sua grandeza, contemplando as dimensões simbólica, econômica e cidadã da cultura, que são parte central do projeto de um país democrático e plural. A pluralidade é nossa singularidade.");
28 62  
29 63 // Programs
30 64 $scale: 1.1;
... ... @@ -53,6 +87,11 @@ body {
53 87 color: #fff;
54 88 padding: 5px;
55 89 margin-top: -5px;
  90 +
  91 + &.icon-small {
  92 + width: 35px;
  93 + height: 35px;
  94 + }
56 95 }
57 96 button {
58 97 border-left: none;
... ... @@ -90,7 +129,7 @@ body {
90 129 @each $category, $color in $categories {
91 130 .#{$category} & {
92 131 background-color: $color;
93   - border-bottom: 3px solid darken($color, $darken);
  132 + border-bottom: 3px solid map-get($categories-complementary-2, $category);
94 133 }
95 134 }
96 135  
... ... @@ -98,7 +137,7 @@ body {
98 137 &:focus {
99 138 @each $category, $color in $categories {
100 139 .#{$category} & {
101   - background-color: darken($color, $darken);
  140 + background-color: map-get($categories-complementary-2, $category);
102 141 }
103 142 }
104 143 }
... ... @@ -181,7 +220,6 @@ body {
181 220 height: 40px;
182 221  
183 222 .icon {
184   - // transform: scale(0.7);
185 223 position: relative;
186 224 top: -8px;
187 225 left: -8px;
... ... @@ -198,7 +236,7 @@ body {
198 236 background-color: #4AC97A;
199 237  
200 238 &:hover { background-color: lighten(#4AC97A, 10%); }
201   -
  239 +
202 240 &:active,
203 241 &:focus { background-color: darken(#4AC97A, 10%)}
204 242 }
... ... @@ -206,7 +244,7 @@ body {
206 244 background-color: #EEB453;
207 245  
208 246 &:hover { background-color: lighten(#EEB453, 10%); }
209   -
  247 +
210 248 &:active,
211 249 &:focus { background-color: darken(#EEB453, 10%)}
212 250 }
... ... @@ -214,7 +252,7 @@ body {
214 252 background-color: #EC4C68;
215 253  
216 254 &:hover { background-color: lighten(#EC4C68, 10%); }
217   -
  255 +
218 256 &:active,
219 257 &:focus { background-color: darken(#EC4C68, 10%)}
220 258 }
... ... @@ -233,8 +271,8 @@ body {
233 271 .#{$category} {
234 272 .color-theme-fg { color: $color; }
235 273 .color-theme-bg { background-color: $color;}
236   - .color-theme-bg-complementar-1 { background-color: lighten($color, 10%);}
237   - .color-theme-bg-complementar-2 { background-color: darken($color, 10%);}
  274 + .color-theme-bg-complementar-1 { background-color: map-get($categories-complementary-1, $category);}
  275 + .color-theme-bg-complementar-2 { background-color: map-get($categories-complementary-2, $category);}
238 276  
239 277 .contraste & .color-theme-fg { color: #fff; }
240 278 .contraste & .color-theme-bg { background-color: #000;}
... ...
src/app/layout.scss
... ... @@ -123,6 +123,11 @@
123 123 margin-left: -2px;
124 124 }
125 125  
  126 +.vertical-padding {
  127 + padding-top: 15px;
  128 + padding-bottom: 15px;
  129 +}
  130 +
126 131 .no-space-left { margin-left: 0; padding-left: 0;}
127 132 .no-space-right { margin-right: 0; padding-right: 0;}
128 133  
... ...
src/app/pages/article/article.controller.js
... ... @@ -6,10 +6,11 @@
6 6 .controller('ArticlePageController', ArticlePageController);
7 7  
8 8 /** @ngInject */
9   - function ArticlePageController(DialogaService, $state, $sce, $log) {
  9 + function ArticlePageController(DialogaService, $rootScope, $state, $sce, $log) {
10 10 var vm = this;
11 11  
12 12 vm.DialogaService = DialogaService;
  13 + vm.$rootScope = $rootScope;
13 14 vm.$state = $state;
14 15 vm.$sce = $sce;
15 16 vm.$log = $log;
... ... @@ -17,6 +18,8 @@
17 18 vm.init();
18 19 vm.loadData();
19 20  
  21 + vm.$rootScope.focusMainContent();
  22 +
20 23 vm.$log.debug('ArticlePageController');
21 24 }
22 25  
... ... @@ -41,7 +44,7 @@
41 44 vm.DialogaService.getTerms(handleSuccess, handleError);
42 45 break;
43 46 default:
44   - vm.$log.warn('Page not handled:', vm.page);
  47 + vm.$log.debug('Page not handled:', vm.page);
45 48 break;
46 49 }
47 50  
... ...
src/app/pages/auth/auth.controller.js
... ... @@ -6,7 +6,7 @@
6 6 .controller('AuthPageController', AuthPageController);
7 7  
8 8 /** @ngInject */
9   - function AuthPageController($scope, $rootScope, $window, $location, $state, $timeout, $interval, AUTH_EVENTS, AuthService, DialogaService, Session, $log) {
  9 + function AuthPageController($scope, $rootScope, $window, $location, $state, $timeout, $interval, APP, AUTH_EVENTS, AuthService, DialogaService, Session, $log) {
10 10 var vm = this;
11 11  
12 12 vm.$scope = $scope;
... ... @@ -16,6 +16,7 @@
16 16 vm.$state = $state;
17 17 vm.$timeout = $timeout;
18 18 vm.$interval = $interval;
  19 + vm.APP = APP;
19 20 vm.AUTH_EVENTS = AUTH_EVENTS;
20 21 vm.AuthService = AuthService;
21 22 vm.DialogaService = DialogaService;
... ... @@ -26,6 +27,8 @@
26 27 vm.loadData();
27 28 vm.attachListeners();
28 29  
  30 + vm.$rootScope.focusMainContent();
  31 +
29 32 vm.$log.debug('AuthPageController');
30 33 }
31 34  
... ... @@ -34,7 +37,7 @@
34 37  
35 38 // init variables
36 39 vm.signin = {};
37   - vm.singup = {};
  40 + vm.signup = {};
38 41 vm.terms = null;
39 42 vm.loadingTerms = null;
40 43 vm.delay = 3; // segundos
... ... @@ -119,16 +122,23 @@
119 122 vm.AuthService.logout();
120 123 };
121 124  
122   - AuthPageController.prototype.submitSingup = function(credentials) {
  125 + AuthPageController.prototype.submitSignup = function($event, credentials) {
123 126 var vm = this;
124 127  
  128 + var target = $event.target;
  129 + var $target = angular.element(target);
  130 + var $captcha = $target.find('[name="txtToken_captcha_serpro_gov_br"]');
  131 + credentials.txtToken_captcha_serpro_gov_br = $captcha.val();
  132 +
  133 + // vm.signupFormStatus = 'SENDIN';
125 134 vm.AuthService.register(credentials).then(function(response) {
126 135 vm.$log.debug('register success.response', response);
127 136  
128 137 // TODO: mensagens de sucesso
129 138 // 'Cadastro efetuado com sucesso.'
130 139 // 'Verifique seu email para confirmar o cadastro.'
131   - vm.successMessage = '<h3>Cadastro efetuado com sucesso.</h3>' + '<p>Verifique seu <b>email</b> para confirmar o cadastro.</p>';
  140 + vm.messageTitle = 'Cadastro efetuado com sucesso!';
  141 + vm.successMessage = 'Verifique seu e-mail para confirmar o cadastro.';
132 142 vm.redirectBack();
133 143 }, function(response) {
134 144 vm.$log.debug('register error.response', response);
... ... @@ -163,11 +173,46 @@
163 173 });
164 174 };
165 175  
  176 + AuthPageController.prototype.submitRecover = function($event, recoverForm) {
  177 + var vm = this;
  178 +
  179 + // get form data
  180 + var data = {
  181 + login: recoverForm.login.$modelValue,
  182 + captcha_text: recoverForm.captcha_text.$modelValue
  183 + };
  184 +
  185 + // get captcha token
  186 + var target = $event.target;
  187 + var $target = angular.element(target);
  188 + var $captcha = $target.find('[name="txtToken_captcha_serpro_gov_br"]');
  189 + data.txtToken_captcha_serpro_gov_br = $captcha.val();
  190 +
  191 + vm.AuthService.forgotPassword(data).then(function(response) {
  192 + vm.$log.debug('recover success.response', response);
  193 +
  194 + vm.successRecoverMessageTitle = 'Pedido enviado sucesso!';
  195 + vm.successRecoverMessage = 'Verifique seu e-mail. Em instantes você receberá um e-mail com um link para redefinir sua senha.';
  196 + // vm.redirectBack();
  197 + }, function(response){
  198 + vm.$log.debug('recover error.response', response);
  199 +
  200 + var message = response.data.message;
  201 + vm.errorRecoverMessage = message;
  202 +
  203 + if(response.data.code === 500){
  204 + vm.internalError = true;
  205 + }
  206 + }).catch(function(error){
  207 + vm.$log.debug('recover catch.error', error);
  208 + });
  209 + };
  210 +
166 211 AuthPageController.prototype.redirectBack = function() {
167 212 var vm = this;
168 213  
169 214 if (!vm.hasRedirect) {
170   - vm.$log.warn('No redirect params defined.');
  215 + vm.$log.debug('No redirect params defined.');
171 216 return;
172 217 }
173 218  
... ... @@ -207,14 +252,15 @@
207 252  
208 253 AuthPageController.prototype.authWithFacebook = function() {
209 254 var vm = this;
210   - var url = 'http://login.dialoga.gov.br/plugin/oauth_client/facebook?oauth_client_popup=true&id=1';
  255 + // var url = 'http://login.dialoga.gov.br/plugin/oauth_client/facebook?oauth_client_popup=true&id=1';
  256 + var url = 'http://login.dialoga.gov.br/plugin/oauth_client/facebook?oauth_client_popup=true&id=' + vm.APP.facebook_app_id;
211 257 vm.$window.oauthClientAction(url);
212 258 };
213 259  
214 260 AuthPageController.prototype.authWithGooglePlus = function() {
215 261 var vm = this;
216 262  
217   - var url = 'http://login.dialoga.gov.br/plugin/oauth_client/google_oauth2?oauth_client_popup=true&id=4';
  263 + var url = 'http://login.dialoga.gov.br/plugin/oauth_client/google_oauth2?oauth_client_popup=true&id=' + vm.APP.goople_app_id;
218 264 vm.$window.oauthClientAction(url);
219 265 };
220 266 })();
... ...
src/app/pages/auth/auth.scss
... ... @@ -92,6 +92,10 @@
92 92 }
93 93 }
94 94 }
  95 +
  96 + .feedback-message {
  97 + padding: 20px 0;
  98 + }
95 99 }
96 100  
97 101 .modal-dialog {
... ...
src/app/pages/auth/recover.html
1   -<div class="container">
2   - <div class="row">
3   - <div class="col-sm-12">
4   - <h2>Esqueci minha senha</h2>
5   - <h5>
6   - Calma, podemos ajudar! Informe o seu e-mail que a gente envia um link de alteração.
7   - </h5>
8   - </div>
9   - </div>
10   -</div>
11   -<section role="main" class="section-gray">
  1 +<div class="page--recover">
12 2 <div class="container">
13 3 <div class="row">
14   - <div ng-if="pageSignin.currentUser">
15   - <div class="row">
16   - <div class="col-sm-8 col-sm-offset-2">
17   - <h3>Você está logado!</h3>
18   - <button type="button" ng-click="pageSignin.onClickLogout()" class="btn btn-primary">Sair</button>
19   - </div>
20   - </div>
  4 + <div class="col-sm-12">
  5 + <h2>Esqueci minha senha</h2>
  6 + <h5>
  7 + Calma, podemos ajudar! Informe o seu e-mail que a gente envia um link de alteração.
  8 + </h5>
21 9 </div>
22   - <div ng-if="!pageSignin.currentUser">
23   - <br>
24   - <div class="col-sm-8 col-sm-offset-2">
25   - <div class="row">
26   - <div class="col-md-12">
27   - <form name="recoverPassForm" ng-submit="pageSignin.login(pageSignin.credentials)">
28   - <div class="form-group">
29   - <label for="inputUsername">E-mail*</label>
30   - <input type="email" id="inputUsername" name="inputUsername" class="form-control input-lg" ng-class="{ 'has-error' : recoverPassForm.inputUsername.$invalid && recoverPassForm.inputUsername.$touched }" ng-model="pageSignin.credentials.username" required />
31   - <validation-messages field=" recoverPassForm.inputUsername"/>
32   - </div>
33   - <div class="form-group">
34   - <div class="input-group">
35   - <label for="inputPassword">Digite o texto desta imagem</label>
36   - <br>
37   - <span>Aqui vai um CAPTCHA</span>
  10 + </div>
  11 + </div>
  12 + <section role="main" class="section-gray vertical-padding">
  13 + <div class="container">
  14 + <div class="row">
  15 + <div ng-if="pageSignin.successRecoverMessage">
  16 + <div class="col-sm-8 col-sm-offset-2">
  17 + <div class="feedback-message">
  18 + <show-message
  19 + type="'success'"
  20 + title="pageSignin.successRecoverMessageTitle || 'Pronto!'"
  21 + message="pageSignin.successRecoverMessage"
  22 + ></show-message>
  23 + <div class="row">
  24 + <div class="col-sm-8 col-sm-offset-4">
  25 + <p><a ui-sref="inicio">Ir para página inicial</a></p>
  26 + </div>
  27 + </div>
  28 + </div>
  29 + </div>
  30 + </div>
  31 + <div ng-if="!pageSignin.successRecoverMessage">
  32 + <br>
  33 + <div class="col-sm-8 col-sm-offset-2">
  34 + <div class="row" ng-if="pageSignin.errorRecoverMessage">
  35 + <div class="col-sm-12">
  36 + <div class="alert alert-danger">{{pageSignin.errorRecoverMessage}}</div>
  37 + <div ng-if="vm.internalError">
  38 + <p>Este erro parece ser um problema interno.<br/>Por favor, tente novamente mais tarde.</p>
  39 + <p>Caso o problema persista, entre em contato!</p>
  40 + <p><a ui-sref="duvidas">Ir para página de contato</a></p>
  41 + </div>
  42 + </div>
  43 + </div>
  44 + <div class="row">
  45 + <div class="col-md-12">
  46 + <form name="recoverPassForm" ng-submit="pageSignin.submitRecover($event, recoverPassForm)">
  47 + <div class="form-group">
  48 + <label for="recover-login">E-mail*</label>
  49 + <input type="email" id="recover-login" name="login" class="form-control input-lg" ng-class="{ 'has-error' : recoverPassForm.login.$invalid && recoverPassForm.login.$touched }" ng-model="pageSignin.credentials.username" required />
  50 + <validation-messages field=" recoverPassForm.login"></validation-messages>
38 51 </div>
39   - </div>
40   - <div class="form-group">
41   - <button class="btn btn-lg btn-block btn-submit" type="submit">Solicitar alteração de senha</button>
42   - </div>
43   - </form>
  52 + <div class="form-group">
  53 + <div id="serpro_captcha" class="captcha">
  54 + </div>
  55 + <div class="captcha">
  56 + Digite os caracteres acima:
  57 + </div>
  58 + <div class="captcha">
  59 + <input type="text" name="captcha_text" id="captcha_text" aria-label="Escreva os caracteres do captcha aqui" ng-model="pageSignin.signup.captcha_text" ng-minlength="" ng-maxlength="" required>
  60 + <validation-messages field="recoverPassForm.captcha_text"></validation-messages>
  61 + </div>
  62 + </div>
  63 + <div class="form-group">
  64 + <button class="btn btn-lg btn-submit" type="submit">Solicitar alteração de senha</button>
  65 + </div>
  66 + </form>
  67 + </div>
44 68 </div>
45 69 </div>
  70 + <br>
46 71 </div>
47   - <br>
48 72 </div>
49 73 </div>
50   - </div>
51   -</section>
  74 + </section>
  75 +</div>
... ...
src/app/pages/auth/signin.html
... ... @@ -11,15 +11,26 @@
11 11 <div ng-if="pageSignin.currentUser">
12 12 <div class="row">
13 13 <div class="col-sm-8 col-sm-offset-2">
14   - <div>
15   - <h3 ng-if="!pageSignin.successMessage">Você está logado!</h3>
16   - <h3 ng-if="pageSignin.successMessage" ng-bind-html="pageSignin.successMessage"></h3>
17   - <div ng-if="pageSignin.countdown > 0">
18   - <p>
19   - Você será redirecionado em menos de <b>{{pageSignin.countdown}} segundos</b>...
20   - </p>
  14 + <div class="feedback-message">
  15 + <show-message
  16 + type="'success'"
  17 + title="pageSignin.messageTitle || 'Você está logado!'"
  18 + message="pageSignin.successMessage"
  19 + ></show-message>
  20 +
  21 + <div class="row">
  22 + <div class="col-sm-4"></div>
  23 + <div class="col-sm-8 text-center-sm">
  24 + <!-- <div ng-if="pageSignin.redirect > 0">
  25 + </div> -->
  26 + <div ng-if="pageSignin.countdown > 0">
  27 + <p>
  28 + Você será redirecionado em menos de <b>{{pageSignin.countdown}} segundos</b>...
  29 + </p>
  30 + </div>
  31 + <button type="button" ng-click="pageSignin.onClickLogout()" class="btn btn-primary">Sair</button>
  32 + </div>
21 33 </div>
22   - <button type="button" ng-click="pageSignin.onClickLogout()" class="btn btn-primary">Sair</button>
23 34 </div>
24 35 </div>
25 36 </div>
... ... @@ -28,22 +39,25 @@
28 39 <div class="col-sm-5">
29 40 <div class="row">
30 41 <div class="col-md-12">
31   - <h2>Já possui cadastro</h2>
  42 + <h2>Já possui cadastro?</h2>
32 43 <p>Use seus dados para acessar o Dialoga Brasil</p>
33 44 <form role="form" name="signinForm" ng-submit="pageSignin.submitSignin(pageSignin.signin)" novalidate>
34 45 <div class="form-group">
35 46 <label for="signin-form--login">E-mail*</label>
36 47 <input type="email" id="signin-form--login" name="login" class="form-control input-lg" ng-class="{ 'has-error' : signinForm.login.$invalid && signinForm.login.$touched }" ng-model="pageSignin.signin.username" required/>
37   - <validation-messages field="signinForm.login"/>
  48 + <validation-messages field="signinForm.login"></validation-messages>
38 49 </div>
39 50 <div class="form-group">
40 51 <label for="signin-form--password">Senha*</label>
41 52 <input type="password" id="signin-form--password" name="password" class="form-control input-lg" ng-class="{ 'has-error' : signinForm.password.$invalid && signinForm.password.$touched }" ng-model="pageSignin.signin.password" required>
42   - <validation-messages field="signinForm.password"/>
  53 + <validation-messages field="signinForm.password"></validation-messages>
43 54 </div>
44 55 <div class="form-group">
45 56 <button class="btn btn-lg btn-block btn-submit" type="submit">Entrar</button>
46 57 </div>
  58 + <div class="form-group">
  59 + <a ui-sref="recuperar" class="btn btn-lg btn-link">Esqueci minha senha</a>
  60 + </div>
47 61 </form>
48 62 </div>
49 63 </div>
... ... @@ -96,31 +110,31 @@
96 110 </div>
97 111 <div class="row">
98 112 <div class="col-sm-12">
99   - <form name="signupForm" ng-submit="pageSignin.submitSigup(pageSignin.signup)">
  113 + <form name="signupForm" ng-submit="pageSignin.submitSignup($event, pageSignin.signup)">
100 114 <div class="form-group">
101 115 <label for="signup-form--name">Nome*:</label>
102 116 <span class="pull-right">*Dados obrigatórios</span>
103 117 <input type="text" id="signup-form--name" name="name" class="form-control input-lg" ng-class="{ 'has-error' : signupForm.name.$invalid && signupForm.name.$touched }" ng-model="pageSignin.signup.name" ng-minlength="" ng-maxlength="" required>
104   - <validation-messages field="signupForm.name"/>
  118 + <validation-messages field="signupForm.name"></validation-messages>
105 119 </div>
106 120 <div class="form-group">
107 121 <label for="signup-form--email">E-mail*:</label>
108 122 <input type="email" id="signup-form--email" name="email" class="form-control input-lg" ng-class="{ 'has-error' : signupForm.email.$invalid && signupForm.email.$touched }" ng-model="pageSignin.signup.email" ng-minlength="" ng-maxlength="" required>
109   - <validation-messages field="signupForm.email"/>
  123 + <validation-messages field="signupForm.email"></validation-messages>
110 124 </div>
111 125 <div class="row">
112 126 <div class="col-sm-6">
113 127 <div class="form-group">
114 128 <label for="signup-form--password">Senha*:</label>
115 129 <input type="password" id="signup-form--password" name="password" class="form-control input-lg" ng-class="{ 'has-error' : signupForm.password.$invalid && signupForm.password.$touched }" ng-model="pageSignin.signup.password" ng-minlength="" ng-maxlength="" required>
116   - <validation-messages field="signupForm.password"/>
  130 + <validation-messages field="signupForm.password"></validation-messages>
117 131 </div>
118 132 </div>
119 133 <div class="col-sm-6">
120 134 <div class="form-group">
121 135 <label for="signup-form--password-confirmation">Confirmar Senha*:</label>
122 136 <input type="password" id="signup-form--password-confirmation" name="password_confirmation" class="form-control input-lg" ng-class="{ 'has-error' : signupForm.password_confirmation.$invalid && signupForm.password_confirmation.$touched }" ng-model="pageSignin.signup.password_confirmation" ng-minlength="" ng-maxlength="" required>
123   - <validation-messages field="signupForm.password_confirmation"/>
  137 + <validation-messages field="signupForm.password_confirmation"></validation-messages>
124 138 </div>
125 139 </div>
126 140 </div>
... ... @@ -141,35 +155,35 @@
141 155 <div class="form-group">
142 156 <div class="checkbox">
143 157 <label for="user_terms_accepted">
144   - <input type="checkbox" id="user_terms_accepted" name="user_terms_accepted" value="aceito" ng-model="pageSignin.signup.user_terms_accepted" required>
  158 + <input type="checkbox" id="user_terms_accepted" name="user_terms_accepted" value="aceito" ng-model="pageSignin.signup.user_terms_accepted" required />
145 159 Já li e concordo com os
146 160 <button type="button" class="btn btn-link" style="padding:0 0 4px 0;" data-toggle="modal" data-target="#modalTermosDeUso">Termos de Uso</button>
147 161 </label>
148 162 </div>
149   - </input>
150   - <validation-messages field="signupForm.user_terms_accepted"/>
151   - </div>
152   - <div class="form-group">
153   - <div id="serpro_captcha" class="captcha">
  163 + <validation-messages field="signupForm.user_terms_accepted"></validation-messages>
154 164 </div>
155   - <div class="captcha">
156   - Digite os caracteres acima:
  165 + <div class="form-group">
  166 + <div id="serpro_captcha" class="captcha">
  167 + </div>
  168 + <div class="captcha">
  169 + Digite os caracteres acima:
  170 + </div>
  171 + <div class="captcha">
  172 + <input type="text" name="captcha_text" id="captcha_text" aria-label="Escreva os caracteres do captcha aqui" ng-model="pageSignin.signup.captcha_text" ng-minlength="" ng-maxlength="" required>
  173 + <validation-messages field="signupForm.captcha_text"></validation-messages>
  174 + </div>
157 175 </div>
158   - <div class="captcha">
159   - <input type="text" name="captcha_text" id="captcha_text" aria-label="Escreva os caracteres do captcha aqui" ng-model="pageSignin.signup.captcha_text">
  176 + <div class="form-group">
  177 + <button type="submit" class="btn btn-lg btn-block btn-submit" ng-class=" {'disabled' : !pageSignin.signup.user_terms_accepted }">Cadastrar</button>
160 178 </div>
161   - </div>
162   - <div class="form-group">
163   - <button class="btn btn-lg btn-block btn-submit" ng-class=" {'disabled' : !pageSignin.signup.user_terms_accepted }" type="submit">Cadastrar</button>
164   - </div>
165   - </form>
  179 + </form>
  180 + </div>
166 181 </div>
167 182 </div>
168 183 </div>
169 184 </div>
170   - </section>
171   -
172   -
  185 + </div>
  186 +</section>
173 187 <div class="modal fade" id="modalTermosDeUso" tabindex="-1" role="dialog" aria-labelledby="termosDeUsoLabel">
174 188 <div class="modal-dialog" role="document">
175 189 <div class="modal-content">
... ...
src/app/pages/inicio/inicio.controller.js
... ... @@ -208,7 +208,7 @@
208 208 var vm = this;
209 209  
210 210 if (!vm.programs) {
211   - vm.$log.warn('No programs loaded yet. Abort.');
  211 + vm.$log.debug('No programs loaded yet. Abort.');
212 212 return null;
213 213 }
214 214  
... ... @@ -220,7 +220,7 @@
220 220 var filter = vm.$filter('filter');
221 221  
222 222 if (selectedTheme) {
223   - output = _filterByCategory(output, selectedTheme);
  223 + output = vm._filterByCategory(output, selectedTheme);
224 224 }
225 225  
226 226 if (query) {
... ... @@ -234,7 +234,9 @@
234 234 return output;
235 235 };
236 236  
237   - function _filterByCategory (input, category) {
  237 + InicioPageController.prototype._filterByCategory = function (input, category) {
  238 + var vm = this;
  239 +
238 240 input = input || [];
239 241  
240 242 if (!category) {
... ... @@ -245,6 +247,12 @@
245 247 var out = [];
246 248 for (var i = 0; i < input.length; i++) {
247 249 var program = input[i];
  250 +
  251 + if(!program.categories || program.categories.length === 0){
  252 + vm.$log.warn('Program without theme (category)', program.slug);
  253 + continue;
  254 + }
  255 +
248 256 if (program.categories[0].slug === category.slug) {
249 257 out.push(program);
250 258 }
... ...
src/app/pages/inicio/inicio.scss
... ... @@ -25,20 +25,6 @@
25 25 }
26 26 }
27 27  
28   - .input-group-search {
29   - .icon-small {
30   - width: 35px;
31   - height: 35px;
32   - }
33   - .icon-circle {
34   - color: #fff;
35   - padding: 5px;
36   - margin-top: -5px;
37   - }
38   - button {
39   - border-left: none;
40   - }
41   - }
42 28 .input-group-btn {
43 29 background-color: #fff;
44 30 }
... ...
src/app/pages/programas/programa.controller.js
... ... @@ -6,25 +6,28 @@
6 6 .controller('ProgramaPageController', ProgramaPageController);
7 7  
8 8 /** @ngInject */
9   - function ProgramaPageController(DialogaService, PATH, VOTE_OPTIONS, $state, $location, $scope, $rootScope, $element, $timeout, $log) {
10   - $log.debug('ProgramaPageController');
11   -
  9 + function ProgramaPageController(DialogaService, PATH, VOTE_OPTIONS, PROPOSAL_STATUS, $state, $location, $scope, $rootScope, $element, $timeout, $sce, $log) {
12 10 var vm = this;
13 11  
14 12 vm.DialogaService = DialogaService;
15 13 vm.PATH = PATH;
16 14 vm.VOTE_OPTIONS = VOTE_OPTIONS;
  15 + vm.PROPOSAL_STATUS = PROPOSAL_STATUS;
17 16 vm.$state = $state;
18 17 vm.$location = $location;
19 18 vm.$scope = $scope;
20 19 vm.$rootScope = $rootScope;
21 20 vm.$element = $element;
22 21 vm.$timeout = $timeout;
  22 + vm.$sce = $sce;
23 23 vm.$log = $log;
24 24  
25 25 vm.init();
26 26 vm.loadData();
27 27 vm.attachListeners();
  28 + vm.$rootScope.focusMainContent();
  29 +
  30 + vm.$log.debug('ProgramaPageController');
28 31 }
29 32  
30 33 ProgramaPageController.prototype.init = function() {
... ... @@ -46,6 +49,7 @@
46 49 var vm = this;
47 50  
48 51 vm.loading = true;
  52 + vm.proposalStatus = null;
49 53  
50 54 // Get program by slug
51 55 var slug = vm.$state.params.slug;
... ... @@ -73,6 +77,10 @@
73 77 };
74 78 }
75 79  
  80 + if(vm.article.body && !vm.article.bodyTrusted){
  81 + vm.article.bodyTrusted = vm.$sce.trustAsHtml(vm.article.body);
  82 + }
  83 +
76 84 vm.loadingTopProposals = true;
77 85 vm.DialogaService.getProposalsByTopicId(vm.article.id, {}, function(data) {
78 86 vm.proposals = data.articles;
... ... @@ -109,13 +117,17 @@
109 117 });
110 118  
111 119 vm.$scope.$on('cadastro-proposa:startSendProposal', function(event, proposal) {
112   - vm.creatingProposal = true;
  120 +
  121 + vm.proposalStatus = vm.PROPOSAL_STATUS.SENDING;
  122 +
113 123 vm.DialogaService.createProposal(proposal, vm.article.id, function(response) {
114 124 vm.$log.debug('response', response);
115   - vm.creatingProposal = false;
  125 + // vm.proposalStatus = vm.PROPOSAL_STATUS.SENT | vm.PROPOSAL_STATUS.SUCCESS;
  126 + vm.proposalStatus = vm.PROPOSAL_STATUS.SUCCESS;
116 127 }, function(error) {
117 128 vm.$log.error(error);
118   - vm.creatingProposal = false;
  129 + // vm.proposalStatus = vm.PROPOSAL_STATUS.SENT | vm.PROPOSAL_STATUS.ERROR;
  130 + vm.proposalStatus = vm.PROPOSAL_STATUS.ERROR;
119 131 });
120 132 });
121 133  
... ... @@ -253,9 +265,9 @@
253 265 vm.$element.find(rule).slideUp();
254 266 };
255 267  
256   - ProgramaPageController.prototype.sendProposal = function() {
  268 + ProgramaPageController.prototype.sendAnotherProposal = function() {
257 269 var vm = this;
258 270  
259   - vm.$log.warn('Not implemented yet: "sendProposal"');
  271 + vm.proposalStatus = null;
260 272 };
261 273 })();
... ...
src/app/pages/programas/programa.html
... ... @@ -18,8 +18,8 @@
18 18 </div>
19 19 </section>
20 20  
21   - <div ng-if="pagePrograma.article.body" ng-class="pagePrograma.category.slug">
22   - <section>
  21 + <div role="main">
  22 + <section ng-if="pagePrograma.article.body" ng-class="pagePrograma.category.slug">
23 23 <div class="container">
24 24 <div class="row">
25 25 <article class="program-preview">
... ... @@ -121,6 +121,14 @@
121 121 </div>
122 122 <div class="proposal-extended-section-content">
123 123 <proposal-list proposals="pagePrograma.proposalsTopFive"></proposal-list>
  124 + <div class="row">
  125 + <div class="col-xs-12">
  126 + <a ui-sref="ranking({tema: pagePrograma.category.slug, programa: pagePrograma.article.slug})" class="btn btn-link">
  127 + <span ng-if="pagePrograma.proposals.length > 1">Veja todas as {{pagePrograma.proposals.length}} propostas</span>
  128 + <span ng-if="pagePrograma.proposals.length === 1">Ir para a página de ranking</span>
  129 + </a>
  130 + </div>
  131 + </div>
124 132 </div>
125 133 </div>
126 134 </section>
... ... @@ -138,16 +146,34 @@
138 146 title="'Você não está logado!'"
139 147 message="'Você precisa estar logado para enviar uma proposta.'"
140 148 ></show-message>
141   - <div class="row">
142   - <div class="col-sm-4"></div>
143   - <div class="col-sm-8 text-center-sm">
144   - <a ui-sref="entrar({redirect_uri: pagePrograma.sendProposalRedirectURI})">Clique aqui para ir para a página de login</a>
145   - </div>
  149 + <div class="row">
  150 + <div class="col-sm-4"></div>
  151 + <div class="col-sm-8 text-center-sm">
  152 + <a ui-sref="entrar({redirect_uri: pagePrograma.sendProposalRedirectURI})">Clique aqui para ir para a página de login</a>
146 153 </div>
  154 + </div>
147 155 </div>
148 156 <div ng-if="pagePrograma.$rootScope.currentUser">
149 157 <div class="proposal-extended-section-content">
150   - <cadastro-proposta program="pagePrograma.article"></cadastro-proposta>
  158 + <div ng-if="pagePrograma.proposalStatus === pagePrograma.PROPOSAL_STATUS.SUCCESS">
  159 + <show-message
  160 + type="'success'"
  161 + title="'Proposta enviada com sucesso!'"
  162 + message="'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.'"
  163 + ></show-message>
  164 + <div class="row">
  165 + <div class="col-sm-4"></div>
  166 + <div class="col-sm-8 text-center-sm">
  167 + <button type="button" class="btn btn-link" ng-click="pagePrograma.sendAnotherProposal()">
  168 + Clique aqui para enviar outra proposta
  169 + </button>
  170 + </div>
  171 + </div>
  172 + </div>
  173 + <div ng-if="pagePrograma.proposalStatus === pagePrograma.PROPOSAL_STATUS.ERROR"></div>
  174 + <div ng-if="!pagePrograma.proposalStatus">
  175 + <cadastro-proposta program="pagePrograma.article" status="pagePrograma.proposalStatus"></cadastro-proposta>
  176 + </div>
151 177 </div>
152 178 </div>
153 179 </div>
... ... @@ -155,7 +181,7 @@
155 181  
156 182 <section class="section-content">
157 183 <article class="program-content" ng-if="pagePrograma.article">
158   - <div ng-bind-html="pagePrograma.article.body"></div>
  184 + <div ng-bind-html="pagePrograma.article.bodyTrusted"></div>
159 185 </article>
160 186 </section>
161 187 </div>
... ...
src/app/pages/programas/programas.controller.js
... ... @@ -6,11 +6,12 @@
6 6 .controller('ProgramasPageController', ProgramasPageController);
7 7  
8 8 /** @ngInject */
9   - function ProgramasPageController(DialogaService, $scope, $location, $filter, $log) {
  9 + function ProgramasPageController(DialogaService, $scope, $rootScope, $location, $filter, $log) {
10 10 var vm = this;
11 11  
12 12 vm.DialogaService = DialogaService;
13 13 vm.$scope = $scope;
  14 + vm.$rootScope = $rootScope;
14 15 vm.$location = $location;
15 16 vm.$filter = $filter;
16 17 vm.$log = $log;
... ... @@ -18,8 +19,9 @@
18 19 vm.init();
19 20 vm.loadData();
20 21 vm.attachListeners();
  22 + vm.$rootScope.focusMainContent();
21 23  
22   - $log.debug('ProgramasPageController');
  24 + vm.$log.debug('ProgramasPageController');
23 25 }
24 26  
25 27 ProgramasPageController.prototype.init = function () {
... ... @@ -159,7 +161,7 @@
159 161 var vm = this;
160 162  
161 163 if(!vm.programs){
162   - vm.$log.warn('No programs loaded yet. Abort.');
  164 + vm.$log.info('No programs loaded yet. Abort.');
163 165 return null;
164 166 }
165 167  
... ... @@ -171,7 +173,7 @@
171 173 var filter = vm.$filter('filter');
172 174  
173 175 if (selectedTheme) {
174   - output = _filterByCategory(output, selectedTheme);
  176 + output = vm._filterByCategory(output, selectedTheme);
175 177 }
176 178  
177 179 if (query) {
... ... @@ -179,13 +181,15 @@
179 181 }
180 182  
181 183 if(!query && !selectedTheme && vm._showAllFlag){
182   - output = _balanceByCategory(output);
  184 + output = vm._balanceByCategory(output);
183 185 }
184 186  
185 187 return output;
186 188 };
187 189  
188   - function _filterByCategory (input, category) {
  190 + ProgramasPageController.prototype._filterByCategory = function (input, category) {
  191 + var vm = this;
  192 +
189 193 input = input || [];
190 194  
191 195 if (!category) {
... ... @@ -196,6 +200,12 @@
196 200 var out = [];
197 201 for (var i = 0; i < input.length; i++) {
198 202 var program = input[i];
  203 +
  204 + if(!program.categories || program.categories.length === 0){
  205 + vm.$log.warn('Program without theme (category)', program.slug);
  206 + continue;
  207 + }
  208 +
199 209 if (program.categories[0].slug === category.slug) {
200 210 out.push(program);
201 211 }
... ... @@ -204,13 +214,21 @@
204 214 return out;
205 215 }
206 216  
207   - function _balanceByCategory (input) {
  217 + ProgramasPageController.prototype._balanceByCategory = function (input) {
  218 + var vm = this;
  219 +
208 220 var result = [];
209 221 var resultByCategory = {};
210 222  
211 223 // divide by categories
212 224 for (var i = 0; i < input.length; i++) {
213 225 var program = input[i];
  226 +
  227 + if(!program.categories || program.categories.length === 0){
  228 + vm.$log.warn('Program without theme (category)', program.slug);
  229 + continue;
  230 + }
  231 +
214 232 var categorySlug = program.categories[0].slug;
215 233  
216 234 if (!resultByCategory[categorySlug]) {
... ...
src/app/pages/programas/programas.html
... ... @@ -6,12 +6,12 @@
6 6 </div>
7 7 </div>
8 8  
9   -<div class="page--programas">
  9 +<div class="page--programas" role="main">
10 10 <section class="section--info">
11 11 <div class="container">
12 12 <div class="row">
13 13 <div class="col-sm-12">
14   - <h1>Programas de governo</h1>
  14 + <h1>Programas</h1>
15 15 </div>
16 16 </div>
17 17 </div>
... ...
src/app/pages/programas/programas.scss
... ... @@ -21,6 +21,16 @@
21 21 background-position: center;
22 22 background-size: cover;
23 23 background-repeat: no-repeat;
  24 +
  25 +
  26 +
  27 + @media screen and (max-width: $screen-xs) {
  28 + // height: 15px;
  29 +
  30 + // .video {
  31 + // height: 290px;
  32 + // }
  33 + }
24 34 }
25 35  
26 36 .program-preview--icon {
... ... @@ -37,8 +47,8 @@
37 47 display: block;
38 48 position: relative;
39 49 top: -8px;
40   - left: -6px;
41   - transform: scale($icon-scale);
  50 + left: -8px;
  51 + // transform: scale($icon-scale);
42 52 }
43 53  
44 54 .contraste & {
... ...
src/app/pages/propostas/propostas.controller.js
1   -/**
2   - * Controlador das páginas:
3   - * - Propostas
4   - * - Ranking
5   - */
6 1 (function() {
7 2 'use strict';
8 3  
... ... @@ -22,7 +17,7 @@
22 17  
23 18 vm.init();
24 19 vm.loadData();
25   - vm.attachListeners();
  20 + // vm.attachListeners(); // attach listeners after load data (SYNC)
26 21  
27 22 $log.debug('PropostasPageController');
28 23 }
... ... @@ -32,6 +27,8 @@
32 27  
33 28 vm.themes = null;
34 29 vm.selectedTheme = null;
  30 + vm.filtredPrograms = null;
  31 + vm.selectedProgram = null;
35 32 vm.proposals = null;
36 33 vm.filtredProposals = null;
37 34 vm.query = null;
... ... @@ -46,30 +43,47 @@
46 43  
47 44 vm.loading = true;
48 45  
49   - // load Proposals
50   - vm.loadingProposals = true;
51   - vm.DialogaService.getProposals({}, function(data){
52   - vm.proposals = data.articles;
53   - vm.filtredProposals = vm.proposals;
54   - vm.loadingProposals = false;
  46 + // Behaviour:
  47 + // 1. Load themes
  48 + // 1. Load Proposals per_page
  49 + // END.
  50 +
  51 + // 1. Load themes
  52 + vm.loadingThemes = true;
  53 + vm.DialogaService.getThemes(function(themes){
  54 + vm.themes = themes;
  55 + vm.loadingThemes = false;
55 56 vm.loading = false;
  57 +
  58 + vm.loadProposals(function (){
  59 + vm.attachListeners();
  60 + });
56 61 }, function (error) {
57 62 vm.error = error;
58 63 vm.$log.error(error);
59   - vm.loadingProposals = false;
  64 + vm.loadingThemes = false;
60 65 vm.loading = false;
61 66 });
  67 + };
62 68  
63   - // load themes
64   - vm.loadingThemes = true;
65   - vm.DialogaService.getThemes(function(themes){
66   - vm.themes = themes;
67   - vm.loadingThemes = false;
  69 + PropostasPageController.prototype.loadProposals = function (cb) {
  70 + var vm = this;
  71 +
  72 + // load Proposals
  73 + vm.loadingProposals = true;
  74 + vm.DialogaService.getProposals({}, function(data){
  75 + vm.proposals = data.articles;
  76 + vm.filtredProposals = vm.proposals;
  77 + vm.loadingProposals = false;
68 78 vm.loading = false;
  79 +
  80 + if(cb){
  81 + cb();
  82 + }
69 83 }, function (error) {
70 84 vm.error = error;
71 85 vm.$log.error(error);
72   - vm.loadingThemes = false;
  86 + vm.loadingProposals = false;
73 87 vm.loading = false;
74 88 });
75 89 };
... ... @@ -81,12 +95,22 @@
81 95 vm.selectedTheme = selectedCategory;
82 96 });
83 97  
84   - vm.$scope.$watch('pagePropostas.selectedTheme', function(newValue/*, oldValue*/) {
  98 + vm.$scope.$watch('pagePropostas.selectedTheme', function(newValue, oldValue) {
85 99 vm.search.tema = newValue ? newValue.slug : null;
86 100 vm.$location.search('tema', vm.search.tema);
87 101 vm.filtredProposals = vm.getFiltredProposals();
88 102 });
89 103  
  104 + vm.$scope.$on('change-selectedTopic', function (event, selectedTopic) {
  105 + vm.selectedProgram = selectedTopic;
  106 + });
  107 +
  108 + vm.$scope.$watch('pagePropostas.selectedProgram', function(newValue, oldValue) {
  109 + vm.search.programa = newValue ? newValue.slug : null;
  110 + vm.$location.search('programa', vm.search.programa);
  111 + vm.filtredProposals = vm.getFiltredProposals();
  112 + });
  113 +
90 114 vm.$scope.$watch('pagePropostas.query', function(newValue/*, oldValue*/) {
91 115 vm.search.filtro = newValue ? newValue : null;
92 116 vm.$location.search('filtro', vm.search.filtro);
... ... @@ -94,34 +118,6 @@
94 118 });
95 119 };
96 120  
97   - PropostasPageController.prototype.filter = function() {
98   - var vm = this;
99   -
100   - if (vm.search && vm.search.tema) {
101   - var slug = vm.search.tema;
102   - vm.$log.debug('filter by theme', slug);
103   -
104   - vm.DialogaService.getThemeBySlug(slug, function(theme){
105   - vm.selectedTheme = theme;
106   - vm.$log.debug('getThemeBySlug.slug', slug);
107   - vm.$log.debug('getThemeBySlug.selectedTheme', theme);
108   - }, function(error){
109   - vm.$log.error('Error when try to "getThemeBySlug"', error);
110   - });
111   - }
112   - };
113   -
114   - PropostasPageController.prototype.showAllPrograms = function($event) {
115   - var vm = this;
116   - $event.stopPropagation();
117   -
118   - vm.resetFilterValues();
119   -
120   - vm._showAllFlag = true;
121   -
122   - vm.filtredPrograms = vm.getFiltredPrograms();
123   - };
124   -
125 121 PropostasPageController.prototype.resetFilterValues = function() {
126 122 var vm = this;
127 123  
... ... @@ -133,7 +129,7 @@
133 129 var vm = this;
134 130  
135 131 if(!vm.proposals){
136   - vm.$log.warn('No proposals loaded yet. Abort.');
  132 + vm.$log.info('No proposals loaded yet. Abort.');
137 133 return null;
138 134 }
139 135  
... ... @@ -141,11 +137,16 @@
141 137 var output = input;
142 138 var query = vm.query;
143 139 var selectedTheme = vm.selectedTheme;
  140 + var selectedProgram = vm.selectedProgram;
144 141  
145 142 var filter = vm.$filter('filter');
146 143  
147 144 if (selectedTheme) {
148   - output = _filterByCategory(output, selectedTheme);
  145 + output = vm._filterByCategory(output, selectedTheme);
  146 + }
  147 +
  148 + if (selectedProgram) {
  149 + output = vm._filterByProgram(output, selectedProgram);
149 150 }
150 151  
151 152 if (query) {
... ... @@ -159,7 +160,9 @@
159 160 return output;
160 161 };
161 162  
162   - function _filterByCategory (input, category) {
  163 + PropostasPageController.prototype._filterByCategory = function (input, category) {
  164 + var vm = this;
  165 +
163 166 input = input || [];
164 167  
165 168 if (!category) {
... ... @@ -178,4 +181,25 @@
178 181 return out;
179 182 }
180 183  
  184 + PropostasPageController.prototype._filterByProgram = function (input, program) {
  185 + var vm = this;
  186 +
  187 + input = input || [];
  188 +
  189 + if (!program) {
  190 + // no filter
  191 + return input;
  192 + }
  193 +
  194 + var out = [];
  195 + for (var i = 0; i < input.length; i++) {
  196 + var proposal = input[i];
  197 + if (proposal.parent.id === program.id) {
  198 + out.push(proposal);
  199 + }
  200 + }
  201 +
  202 + return out;
  203 + }
  204 +
181 205 })();
... ...
src/app/pages/propostas/propostas.scss
... ... @@ -2,4 +2,8 @@
2 2 .proposal-box--middle {
3 3 background-color: #fff;
4 4 }
  5 +
  6 + .topics-select--wrapper {
  7 + margin: 20px 0;
  8 + }
5 9 }
... ...
src/app/pages/propostas/ranking.html
... ... @@ -1,98 +0,0 @@
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   -
9   -<div class="page--propostas">
10   - <section class="section--info">
11   - <div class="container">
12   - <div class="row">
13   - <div class="col-sm-12">
14   - <h1>Ranking</h1>
15   - </div>
16   - </div>
17   - </div>
18   - </section>
19   - <section class="section--articles section-gray section-space-up" ng-if="pagePropostas.proposals">
20   - <div class="container">
21   - <div id="lista-de-propostas" class="row">
22   - <div class="col-sm-4 col-md-3">
23   - <div class="row visible-xs">
24   - <div class="col-xs-12">
25   - <div class="input-group input-group-lg input-group-search">
26   - <label for="articleQueryFilter" class="control-label sr-only">Buscar propostas:</label>
27   - <input id="articleQueryFilter" type="search" class="form-control input-search" ng-model="pagePropostas.query" placeholder="Buscar propostas" aria-label="Buscar propostas" >
28   - <span class="input-group-btn">
29   - <button type="button" class="btn btn-default" ng-click="pagePropostas.search()">
30   - <span class="icon-circle icon-small color-theme-common-bg">
31   - <span class="glyphicon glyphicon-search"></span>
32   - </span>
33   - <span class="sr-only">Buscar</span>
34   - </button>
35   - </span>
36   - </div>
37   - <br/>
38   - </div>
39   - </div>
40   - <div ng-if="pagePropostas.themes">
41   - <category-list categories="pagePropostas.themes" selected-category="pagePropostas.selectedTheme"></category-list>
42   - </div>
43   - <div ng-if="!pagePropostas.themes && pagePropostas.loadingThemes">
44   - <div class="alert alert-info" role="alert">
45   - Carregando temas.
46   - </div>
47   - </div>
48   - <div ng-if="!pagePropostas.themes && pagePropostas.themesError">
49   - <div class="alert alert-danger" role="alert">
50   - Não foi possível carregar a lista de temas neste momento.
51   - </div>
52   - </div>
53   - </div>
54   - <div class="col-sm-8 col-md-9">
55   - <div class="row hidden-xs">
56   - <div class="col-xs-12">
57   - <div class="input-group input-group-lg input-group-search">
58   - <label for="articleQueryFilter" class="control-label sr-only">Buscar propostas:</label>
59   - <input id="articleQueryFilter" type="search" class="form-control input-search" ng-model="pagePropostas.query" placeholder="Buscar propostas" aria-label="Buscar propostas" >
60   - <span class="input-group-btn">
61   - <button type="button" class="btn btn-default" ng-click="pagePropostas.search()">
62   - <span class="icon-circle icon-small color-theme-common-bg">
63   - <span class="glyphicon glyphicon-search"></span>
64   - </span>
65   - <span class="sr-only">Buscar</span>
66   - </button>
67   - </span>
68   - </div>
69   - </div>
70   - </div>
71   - <div class="row">
72   - <div class="col-sm-12">
73   - <header class="header">
74   - <h2>Total de Propostas: "<span>{{pagePropostas.filtredProposals.length}} propostas</span>"</h2>
75   - </header>
76   - </div>
77   - </div>
78   -
79   - <div class="row">
80   - <div class="col-sm-12" ng-if="pagePropostas.proposals">
81   - <proposal-list proposals="pagePropostas.filtredProposals" per-page="10"></proposal-list>
82   - </div>
83   - <div ng-if="!pagePropostas.proposals && pagePropostas.loadingProposals">
84   - <div class="alert alert-info" role="alert">
85   - Carregando propostas.
86   - </div>
87   - </div>
88   - <div ng-if="!pagePropostas.proposals && pagePropostas.proposalsError">
89   - <div class="alert alert-danger" role="alert">
90   - Não foi possível carregar a lista de propostas neste momento.
91   - </div>
92   - </div>
93   - </div>
94   - </div>
95   - </div>
96   - </div>
97   - </section>
98   -</div>
src/app/pages/ranking/ranking.controller.js 0 → 100644
... ... @@ -0,0 +1,239 @@
  1 +(function() {
  2 + 'use strict';
  3 +
  4 + angular
  5 + .module('dialoga')
  6 + .controller('RankingPageController', RankingPageController);
  7 +
  8 + /** @ngInject */
  9 + function RankingPageController(DialogaService, $scope, $location, $filter, $log) {
  10 + var vm = this;
  11 +
  12 + vm.DialogaService = DialogaService;
  13 + vm.$scope = $scope;
  14 + vm.$location = $location;
  15 + vm.$filter = $filter;
  16 + vm.$log = $log;
  17 +
  18 + vm.init();
  19 + vm.loadData();
  20 + // vm.attachListeners(); // attach listeners after load data (SYNC)
  21 +
  22 + $log.debug('RankingPageController');
  23 + }
  24 +
  25 + RankingPageController.prototype.init = function () {
  26 + var vm = this;
  27 +
  28 + vm.page = 1;
  29 + vm.per_page = 20;
  30 + vm.themes = null;
  31 + vm.selectedTheme = null;
  32 + vm.filtredPrograms = null;
  33 + vm.selectedProgram = null;
  34 + vm.proposals = null;
  35 + vm.filtredProposals = null;
  36 + vm.query = null;
  37 + vm.search = vm.$location.search();
  38 +
  39 + vm.loading = null;
  40 + vm.error = null;
  41 + };
  42 +
  43 + RankingPageController.prototype.loadData = function () {
  44 + var vm = this;
  45 +
  46 + vm.loading = true;
  47 +
  48 + // Behaviour:
  49 + // 1. Load themes
  50 + // 2. Select a Random Theme (T)
  51 + // 3. Load programs of T
  52 + // 4. Select a random program of T
  53 + // 5. Filter the list of proposals
  54 + // END.
  55 +
  56 + // 1. Load themes
  57 + vm.loadingThemes = true;
  58 + vm.DialogaService.getThemes(function(themes){
  59 + vm.themes = themes;
  60 + vm.loadingThemes = false;
  61 +
  62 + // 2. Select a Random Theme (T)
  63 + var selectedTheme = null;
  64 + if(vm.search.tema){
  65 +
  66 + // vanilla filter
  67 + var results = vm.themes.filter(function(t){
  68 + return t.slug === vm.search.tema;
  69 + });
  70 +
  71 + if(results && results.length > 0){
  72 + selectedTheme = results[0];
  73 + vm.selectedTheme = selectedTheme;
  74 + }
  75 + }
  76 +
  77 + if(!selectedTheme){
  78 + vm.selectedTheme = vm.themes[Math.floor(Math.random() * vm.themes.length)];
  79 + }
  80 +
  81 + // 3. Load programs of T
  82 + // (AND 4)
  83 + var themeId = vm.selectedTheme.id;
  84 + vm.loadPrograms(themeId, function(){
  85 + vm.loadProposals();
  86 + vm.loading = false;
  87 + });
  88 + }, function (error) {
  89 + vm.error = error;
  90 + vm.$log.error(error);
  91 + vm.loadingThemes = false;
  92 + vm.loading = false;
  93 + });
  94 + };
  95 +
  96 + RankingPageController.prototype.loadPrograms = function (themeId, cb) {
  97 + var vm = this;
  98 +
  99 + vm.DialogaService.getProgramsByThemeId(themeId, function (programs){
  100 +
  101 + vm.filtredPrograms = programs;
  102 +
  103 + // 4. Select a random program of T
  104 + var selectedProgram = null;
  105 + if(vm.search.programa){
  106 +
  107 + // vanilla filter
  108 + var results = vm.filtredPrograms.filter(function(p){
  109 + return p.slug === vm.search.programa;
  110 + });
  111 +
  112 + if(results && results.length > 0){
  113 + selectedProgram = results[0];
  114 + vm.selectedProgram = selectedProgram;
  115 + }
  116 + }
  117 +
  118 + if(!selectedProgram){
  119 + vm.selectedProgram = vm.filtredPrograms[Math.floor(Math.random() * vm.filtredPrograms.length)];
  120 + }
  121 +
  122 + if(cb){
  123 + cb();
  124 + }
  125 + }, function(error){
  126 + vm.$log.error(error);
  127 + if(cb){
  128 + cb();
  129 + }
  130 + });
  131 + };
  132 +
  133 + RankingPageController.prototype.loadProposals = function () {
  134 + var vm = this;
  135 +
  136 + // load Proposals
  137 + vm.loadingProposals = true;
  138 + vm.DialogaService.getProposals({
  139 + page: vm.page,
  140 + per_page: vm.per_page
  141 + }, function(data){
  142 + vm.proposals = data.articles;
  143 + vm.filtredProposals = vm.proposals;
  144 + vm.loadingProposals = false;
  145 +
  146 + vm.attachListeners();
  147 + }, function (error) {
  148 + vm.error = error;
  149 + vm.$log.error(error);
  150 + vm.loadingProposals = false;
  151 + });
  152 + };
  153 +
  154 + RankingPageController.prototype.attachListeners = function() {
  155 + var vm = this;
  156 +
  157 + vm.$scope.$on('change-selectedCategory', function (event, selectedCategory) {
  158 + vm.selectedTheme = selectedCategory;
  159 + });
  160 +
  161 + vm.$scope.$watch('pageRanking.selectedTheme', function(newValue/*, oldValue*/) {
  162 + vm.search.tema = newValue ? newValue.slug : null;
  163 + vm.$location.search('tema', vm.search.tema);
  164 +
  165 + if(vm.selectedTheme && vm.selectedTheme.id){
  166 + vm.loadPrograms(vm.selectedTheme.id, function(){
  167 + vm.filterProposals();
  168 + });
  169 + }
  170 + });
  171 +
  172 + vm.$scope.$on('change-selectedTopic', function (event, selectedTopic) {
  173 + vm.selectedProgram = selectedTopic;
  174 + });
  175 +
  176 + vm.$scope.$watch('pageRanking.selectedProgram', function(newValue/*, oldValue*/) {
  177 + vm.search.programa = newValue ? newValue.slug : null;
  178 + vm.$location.search('programa', vm.search.programa);
  179 + vm.filterProposals();
  180 + });
  181 +
  182 + vm.$scope.$watch('pageRanking.query', function(newValue/*, oldValue*/) {
  183 + vm.search.filtro = newValue ? newValue : null;
  184 + vm.$location.search('filtro', vm.search.filtro);
  185 + vm.filterProposals();
  186 + });
  187 + };
  188 +
  189 + RankingPageController.prototype.resetFilterValues = function() {
  190 + var vm = this;
  191 +
  192 + vm.query = null;
  193 + vm.selectedTheme = null;
  194 + };
  195 +
  196 + RankingPageController.prototype.changePage = function(pageIndex) {
  197 + var vm = this;
  198 +
  199 + vm.page = pageIndex;
  200 + vm.filterProposals(pageIndex);
  201 + };
  202 +
  203 + RankingPageController.prototype.filterProposals = function(_page, _per_page) {
  204 + var vm = this;
  205 +
  206 + if (vm.loadingProposals){
  207 + vm.$log.debug('Content is not loaded yet.');
  208 + return;
  209 + }
  210 +
  211 + var page = _page || vm.page;
  212 + var per_page = _per_page || vm.per_page;
  213 + var query = vm.query;
  214 + var selectedProgram = vm.selectedProgram;
  215 +
  216 + if (selectedProgram) {
  217 + var params = {
  218 + page: page,
  219 + per_page: per_page,
  220 + parent_id: selectedProgram.id
  221 + };
  222 +
  223 + if (query) {params.query = query; }
  224 +
  225 + vm.loadingProposals = true;
  226 + vm.DialogaService.searchProposals(params, function(data){
  227 + vm.total_proposals = parseInt(data._obj.headers('total'));
  228 + vm.filtredProposals = data.articles;
  229 + vm.loadingProposals = false;
  230 + }, function (error) {
  231 + vm.error = error;
  232 + vm.$log.error(error);
  233 + vm.loadingProposals = false;
  234 + });
  235 + } else {
  236 + vm.filtredProposals = [];
  237 + }
  238 + };
  239 +})();
... ...
src/app/pages/ranking/ranking.html 0 → 100644
... ... @@ -0,0 +1,74 @@
  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 +
  9 +<div class="page--propostas">
  10 + <section class="section--info">
  11 + <div class="container">
  12 + <div class="row">
  13 + <div class="col-sm-12">
  14 + <h1>Ranking</h1>
  15 + </div>
  16 + </div>
  17 + </div>
  18 + </section>
  19 + <section class="section--articles section-gray section-space-up" ng-if="pageRanking.proposals">
  20 + <div class="container">
  21 + <div id="lista-de-propostas" class="row">
  22 + <div class="col-sm-4 col-md-3">
  23 + <div ng-if="pageRanking.themes">
  24 + <category-list categories="pageRanking.themes" selected-category="pageRanking.selectedTheme" disable-unselect="true"></category-list>
  25 + </div>
  26 + <div ng-if="pageRanking.filtredPrograms && pageRanking.selectedProgram" class="topics-select--wrapper">
  27 + <topics-select topics="pageRanking.filtredPrograms" selected-topic="pageRanking.selectedProgram"></topics-select>
  28 + </div>
  29 + <div ng-if="!pageRanking.themes && pageRanking.loadingThemes">
  30 + <div class="alert alert-info" role="alert">
  31 + Carregando temas.
  32 + </div>
  33 + </div>
  34 + <div ng-if="!pageRanking.themes && pageRanking.themesError">
  35 + <div class="alert alert-danger" role="alert">
  36 + Não foi possível carregar a lista de temas neste momento.
  37 + </div>
  38 + </div>
  39 + </div>
  40 + <div class="col-sm-8 col-md-9">
  41 + <div class="row">
  42 + <div class="col-sm-12">
  43 + <header class="header">
  44 + <h2 style="margin-top:0;">Total de Propostas: "<span>{{pageRanking.total_proposals}} propostas</span>"</h2>
  45 + </header>
  46 + </div>
  47 + </div>
  48 +
  49 + <div class="row">
  50 + <div class="col-sm-12" ng-if="pageRanking.filtredProposals && pageRanking.total_proposals">
  51 + <proposal-list proposals="pageRanking.filtredProposals" per-page="pageRanking.per_page" total="pageRanking.total_proposals"></proposal-list>
  52 + <app-paginator
  53 + page="pageRanking.page"
  54 + per-page="pageRanking.per_page"
  55 + total="pageRanking.total_proposals"
  56 + change-page="pageRanking.changePage(pageIndex)"
  57 + ></app-paginator>
  58 + </div>
  59 + <div class="col-sm-12" ng-if="pageRanking.loadingProposals">
  60 + <div class="alert alert-info" role="alert">
  61 + Carregando propostas.
  62 + </div>
  63 + </div>
  64 + <div class="col-sm-12" ng-if="pageRanking.proposalsError">
  65 + <div class="alert alert-danger" role="alert">
  66 + Não foi possível carregar a lista de propostas neste momento.
  67 + </div>
  68 + </div>
  69 + </div>
  70 + </div>
  71 + </div>
  72 + </div>
  73 + </section>
  74 +</div>
... ...
src/assets/images/icons/tema-agricultura-small.png 0 → 100644

1.48 KB

src/assets/images/icons/tema-cidades-small.png 0 → 100644

1.2 KB

src/assets/images/icons/tema-cultura-small.png 0 → 100644

1.14 KB

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

1.86 KB | W: | H:

2.24 KB | W: | H:

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

1.39 KB

src/assets/images/icons/tema-educacao-small.png 0 → 100644

1.3 KB

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

3.2 KB | W: | H:

2.74 KB | W: | H:

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

1.21 KB

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

1.16 KB

src/assets/images/icons/tema-igualdade-small.png 0 → 100644

1.32 KB

src/assets/images/icons/tema-infraestrutura-small.png 0 → 100644

1.53 KB

src/assets/images/icons/tema-meio-ambiente-small.png 0 → 100644

1.03 KB

src/assets/images/icons/tema-meio-ambiente.png

1.91 KB | W: | H:

1.9 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin
src/assets/images/icons/tema-reducao-da-pobreza-small.png 0 → 100644

1.33 KB

src/assets/images/icons/tema-reducao-da-pobreza.png

2.94 KB | W: | H:

2.55 KB | W: | H:

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

1.05 KB

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

2.19 KB | W: | H:

2.07 KB | W: | H:

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

1.24 KB

src/assets/images/icons/tema-seguranca-publica.png

2.86 KB | W: | H:

2.47 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin
src/assets/images/icons/tema-trabalho-emprego-e-renda-small.png 0 → 100644

1.24 KB

src/index.html
... ... @@ -38,9 +38,10 @@
38 38 <![endif]-->
39 39  
40 40 <app-header></app-header>
41   -
  41 +
42 42 <div id="content" ui-view="main"></div>
43   - <div ui-view="footer"></div>
  43 +
  44 + <app-footer></app-footer>
44 45  
45 46 <div id="footer-brasil"></div>
46 47  
... ...