Commit 16e8e39b473b3fa0bd4ba6f9d754ab3c8d730dcd

Authored by Leonardo Merlin
1 parent 605dc1c5

refact Service finshed

TROUBLESHOOTING.md 0 → 100644
... ... @@ -0,0 +1,7 @@
  1 +- Erro com `lwip` ou `make: g++: Command not found`
  2 + - Solução:
  3 + 1. Instalar dependências do g++: `sudo apt-get install build-essential g++`
  4 + 2. Reinstalar o sprity:
  5 + 1. desinstalar: ``npm uninstall sprity``
  6 + 2. limpar cache: ``npm cache clear``
  7 + 3. instalar: ``npm install sprity``
0 8 \ No newline at end of file
... ...
src/app/components/article-box/article-box.directive.js
... ... @@ -27,20 +27,15 @@
27 27 }
28 28  
29 29 if(!vm.category){
30   - vm.category = vm.article.categories[0];
  30 + throw { name: 'NotDefined', message: 'The attribute "category" is undefined.'};
31 31 }
32 32  
33   - if(!vm.banner && vm.article.image){
34   - vm.banner = {
  33 + if(!vm.image && vm.article.image){
  34 + vm.image = {
35 35 src: $rootScope.basePath + vm.article.image.url,
36 36 alt: 'Imagem de destaque do conteúdo'
37 37 };
38 38 }
39   -
40   - // if(vm.article.color && !vm.article.bgColor){
41   - // // 15% more darker
42   - // vm.article.colorDarker = window.ColorLuminance(vm.article.color, 0.15);
43   - // }
44 39 };
45 40  
46 41 ArticleBoxController.prototype.showContent = function () {
... ... @@ -57,7 +52,8 @@
57 52 restrict: 'E',
58 53 templateUrl: 'app/components/article-box/article-box.html',
59 54 scope: {
60   - article: '='
  55 + article: '=',
  56 + category: '='
61 57 },
62 58 controller: ArticleBoxController,
63 59 controllerAs: 'vm',
... ...
src/app/components/article-box/article-box.html
1 1 <article class="article-box" ng-click="vm.showContent()" ng-class="vm.category.slug">
2 2 <div>
3   - <h2 class="article-box--category">{{vm.category.name}}</h2>
  3 + <h2 class="article-box--category">{{ ::vm.category.name }}</h2>
4 4 <div class="article-box--image-wrapper">
5   - <!-- <img class="article-box--image img-responsive" ng-src="{{vm.banner.src}}" alt="{{vm.banner.alt}}" /> -->
6   - <div class="article-box--image" ng-style="{'background-image':'url( {{vm.banner.src}} )'}"></div>
  5 + <div class="article-box--image" ng-style="{ 'background-image' : 'url({{ vm.image.src }})' }"></div>
7 6 </div>
8 7 <div class="article-box--title">
9 8 <h1>{{::vm.article.title}}</h1>
... ...
src/app/components/article-grid/article-grid.directive.js
... ... @@ -9,7 +9,7 @@
9 9 function articleGrid() {
10 10  
11 11 /** @ngInject */
12   - function ArticleGridController($scope, $rootScope, $element, ArticleService, $location, $filter, $log) {
  12 + function ArticleGridController($scope, $rootScope, $element, $location, $filter, $log) {
13 13 $log.debug('ArticleGridController');
14 14  
15 15 // alias
... ... @@ -19,7 +19,6 @@
19 19 vm.$scope = $scope;
20 20 vm.$rootScope = $rootScope;
21 21 vm.$element = $element;
22   - vm.ArticleService = ArticleService;
23 22 vm.$location = $location;
24 23 vm.$filter = $filter;
25 24 vm.$log = $log;
... ... @@ -27,280 +26,29 @@
27 26  
28 27 // initialization
29 28 vm.init();
  29 + vm.loadData();
  30 + vm.attachListeners();
30 31 }
31 32  
32 33 ArticleGridController.prototype.init = function() {
33   - var vm = this;
34   -
35   - vm.articles = null;
36   - vm.filtredArticleList = null;
37   - vm.categories = null;
38   -
39   - vm.orderCriteries = [
40   - { label: 'Título', name: 'titulo' },
41   - { label: 'Tema', name: 'tema' },
42   - { label: 'Aleatório', name: 'aleatorio' }
43   - ];
44   -
45   - vm.search = vm.$location.search();
46   -
47   - // Add initial values for the filter
48   - vm.query = (vm.search && vm.search.filtro) ? vm.search.filtro : null;
49   - vm.limitTo = (vm.search && vm.search.limite) ? parseInt(vm.search.limite, 10) : vm.defaultLimit;
50   - vm.orderCriteria = (vm.search && vm.search.ordem) ? { name: vm.search.ordem } : null;
51   - vm.reverse = (vm.search && vm.search.reverso) ? true : false;
52   -
53   - // vm.selectedCategory = (vm.search && vm.search.tema) ? vm.getCategoryBySlug(vm.search.tema) : null;
54   - if (vm.search && vm.search.tema) {
55   - var slug = vm.search.tema;
56   - vm.ArticleService.getCategoryBySlug(slug, function(category){
57   - vm.selectedCategory = category;
58   - }, function(error){
59   - vm.$log.error('Error when try to "getCategoryBySlug"', error);
60   - });
61   - }
62   -
63   - if (!angular.equals({}, vm.search)) {
64   - var $el = vm.$element;
65   - angular.element('body').animate({scrollTop: $el.offset().top}, 'slow');
66   - }
67   -
68   - vm.loadData(function(){
69   - vm.filtredArticleList = vm.getFiltredArticles();
70   - });
71   -
72   - vm.attachListeners();
73   - };
74   -
75   - ArticleGridController.prototype.attachListeners = function() {
76   - var vm = this;
77   -
78   - // update window location params
79   - vm.$scope.$on('change-selectedCategory', function(event, selectedCategory){
80   - vm.selectedCategory = selectedCategory;
81   - });
82   -
83   - vm.$scope.$watch('vm.query', function(newValue/*, oldValue*/) {
84   - vm.search.filtro = newValue ? newValue : null;
85   - vm.$location.search('filtro', vm.search.filtro);
86   - if(vm.search.filtro){
87   - vm.limitTo = vm.articles.length;
88   - }else{
89   - vm.limitTo = vm.defaultLimit;
90   - }
91   - vm.filtredArticleList = vm.getFiltredArticles();
92   - });
93   -
94   - vm.$scope.$watch('vm.limitTo', function(newValue/*, oldValue*/) {
95   - vm.search.limite = (newValue && newValue !== vm.defaultLimit) ? newValue : null;
96   - vm.$location.search('limite', vm.search.limite);
97   - vm.filtredArticleList = vm.getFiltredArticles();
98   - });
99   -
100   - vm.$scope.$watch('vm.selectedCategory', function(newValue/*, oldValue*/) {
101   - vm.search.tema = newValue ? newValue.slug : null;
102   - vm.$location.search('tema', vm.search.tema);
103   - if(vm.search.tema){
104   - vm.limitTo = vm.articles.length;
105   - }else{
106   - vm.limitTo = vm.defaultLimit;
107   - }
108   - vm.filtredArticleList = vm.getFiltredArticles();
109   - });
110   -
111   - vm.$scope.$watch('vm.orderCriteria', function(newValue/*, oldValue*/) {
112   - vm.search.ordem = (newValue && newValue.name) ? newValue.name : null;
113   - vm.$location.search('ordem', vm.search.ordem);
114   - vm.filtredArticleList = vm.getFiltredArticles();
115   - });
116   -
117   - vm.$scope.$watch('vm.reverse', function(newValue/*, oldValue*/) {
118   - vm.search.reverso = newValue ? newValue : null;
119   - vm.$location.search('reverso', vm.search.reverso);
120   - vm.filtredArticleList = vm.getFiltredArticles();
121   - });
122   -
123   - };
124   - ArticleGridController.prototype.loadData = function(cb) {
125   - var vm = this;
126   -
127   - var articlesLoaded = false;
128   - var categoriesLoaded = false;
129   -
130   - vm.ArticleService.getPrograms(function(programs){
131   - vm.articles = programs;
132   - articlesLoaded = true;
133   - endLoad();
134   - });
135   -
136   - vm.ArticleService.getCategories(function(categories){
137   - vm.categories = categories;
138   - categoriesLoaded = true;
139   - endLoad();
140   - });
141   -
142   - function endLoad () {
143   - if(articlesLoaded && categoriesLoaded){
144   - cb();
145   - }
146   - }
147   - };
148   -
149   - ArticleGridController.prototype.resetFilterValues = function() {
150   - var vm = this;
151   -
152   - vm.query = null;
153   - vm.limitTo = vm.defaultLimit;
154   - vm.selectedCategory = null;
155   - vm.orderCriteria = null;
156   - };
157   -
158   - ArticleGridController.prototype.getIconClasses = function(category) {
159   - var vm = this;
160   -
161   - vm.$log.debug('[TODO] getIconClasses of category:', category);
162   - return 'glyphicon glyphicon-exclamation-sign';
163   - };
164   -
165   - ArticleGridController.prototype.getCategoryBySlug = function(categorySlug) {
166   - var vm = this;
167   - var result = null;
168   -
169   - angular.forEach(vm.categories, function(value/*, key*/) {
170   - if (value.slug === categorySlug) {
171   - result = value;
172   - }
173   - });
174   -
175   - return result;
  34 + // var vm = this;
  35 + // vm.programs = null; // scope var
176 36 };
177 37  
178   - ArticleGridController.prototype.showAll = function($event) {
179   - var vm = this;
180   -
181   - $event.stopPropagation();
182   -
183   - vm.resetFilterValues();
184   - vm.limitTo = vm.articles.length;
  38 + ArticleGridController.prototype.loadData = function() {
  39 + // var vm = this;
185 40 };
186 41  
187   - ArticleGridController.prototype.getFiltredArticles = function() {
188   - var vm = this;
189   -
190   - if(!vm.articles){
191   - vm.$log.warn('No articles loaded yet. Abort.');
192   - return null;
193   - }
194   -
195   - var input = vm.articles;
196   - var output = input;
197   - var query = vm.query;
198   - var selectedCategory = vm.selectedCategory;
199   - var orderCriteria = vm.orderCriteria ? vm.orderCriteria : { name : 'aleatorio'};
200   - var filter = vm.$filter('filter');
201   - var orderBy = vm.$filter('orderBy');
202   - var limitTo = vm.$filter('limitTo');
203   - var limit = vm.limitTo ? vm.limitTo : 4;
204   -
205   - if (selectedCategory) {
206   - output = _filterByCategory(output, selectedCategory);
207   - }
208   -
209   - if (query) {
210   - output = filter(output, query, false);
211   - }
212   -
213   - switch (orderCriteria.name) {
214   - case 'titulo':
215   - output = orderBy(output, 'title', vm.reverse);
216   - break;
217   - case 'tema':
218   - output = orderBy(output, 'categories[0].name', vm.reverse);
219   - break;
220   - case 'more_participants':
221   - vm.$log.info('Criteria not handled yet: ', orderCriteria);
222   - break;
223   - case 'aleatorio':
224   - // shuffling
225   - // if (!vm._isShuffled){
226   - output = vm.filterShuffle(output);
227   - // vm._isShuffled = true;
228   - // }
229   -
230   - if (vm.reverse) {
231   - output = output.slice().reverse();
232   - }
233   -
234   - break;
235   - default:
236   - vm.$log.warn('Criteria not matched: ', orderCriteria);
237   - break;
238   - }
239   -
240   - output = limitTo(output, limit);
241   -
242   - return output;
243   - };
244   -
245   - ArticleGridController.prototype.filterShuffle = function(input) {
246   - var result = [];
247   - var resultByCategory = {};
248   -
249   - // divide by categories
250   - for (var i = 0; i < input.length; i++) {
251   - var program = input[i];
252   - var categorySlug = program.categories[0].slug;
253   -
254   - if (!resultByCategory[categorySlug]) {
255   - resultByCategory[categorySlug] = [];
256   - }
257   -
258   - resultByCategory[categorySlug].push(program);
259   - }
260   -
261   - // shuffle each array
262   - var prop = null;
263   - var categoryWithPrograms = null;
264   - for (prop in resultByCategory) {
265   - if (resultByCategory.hasOwnProperty(prop)) {
266   - categoryWithPrograms = resultByCategory[prop];
267   - resultByCategory[prop] = shuffle(categoryWithPrograms);
268   - }
269   - }
270   -
271   - // Concat all into result array
272   - // > while has program at Lists on resultByCategory
273   - var hasProgram = true;
274   - while (hasProgram) {
275   -
276   - var foundProgram = false;
277   - // each categoryList with array of program
278   - prop = null;
279   - categoryWithPrograms = null;
280   - for (prop in resultByCategory) {
281   -
282   - if (resultByCategory.hasOwnProperty(prop)) {
283   - categoryWithPrograms = resultByCategory[prop];
284   -
285   - if (categoryWithPrograms.length > 0) {
286   - var pivotProgram = categoryWithPrograms.pop();
287   - result.push(pivotProgram);
288   - foundProgram = true;
289   - }
290   - }
291   - }
292   -
293   - if (!foundProgram) {
294   - hasProgram = false;
295   - }
296   - }
297   -
298   - return result;
  42 + ArticleGridController.prototype.attachListeners = function() {
  43 + // var vm = this;
299 44 };
300 45  
301 46 var directive = {
302 47 restrict: 'E',
303 48 templateUrl: 'app/components/article-grid/article-grid.html',
  49 + scope: {
  50 + articles: '='
  51 + },
304 52 controller: ArticleGridController,
305 53 controllerAs: 'vm',
306 54 bindToController: true
... ... @@ -308,44 +56,4 @@
308 56  
309 57 return directive;
310 58 }
311   -
312   - function _filterByCategory (input, category) {
313   - input = input || [];
314   -
315   - if (!category) {
316   - // no filter
317   - return input;
318   - }
319   -
320   - var out = [];
321   - for (var i = 0; i < input.length; i++) {
322   - var program = input[i];
323   - if (program.categories[0].slug === category.slug) {
324   - out.push(program);
325   - }
326   - }
327   -
328   - return out;
329   - }
330   -
331   - // -> Fisher–Yates shuffle algorithm
332   - function shuffle (array) {
333   - var currentIndex = array.length, temporaryValue, randomIndex ;
334   -
335   - // While there remain elements to shuffle...
336   - while (0 !== currentIndex) {
337   -
338   - // Pick a remaining element...
339   - randomIndex = Math.floor(Math.random() * currentIndex);
340   - currentIndex -= 1;
341   -
342   - // And swap it with the current element.
343   - temporaryValue = array[currentIndex];
344   - array[currentIndex] = array[randomIndex];
345   - array[randomIndex] = temporaryValue;
346   - }
347   -
348   - return array;
349   - }
350   -
351 59 })();
... ...
src/app/components/article-grid/article-grid.html
1   -<article class="article-grid">
2   - <header class="header">
3   - <h2>Conheça os programas <span class="small">({{vm.filtredArticleList.length}}/{{::vm.articles.length}})</span></h2>
4   - <button type="button" class="btn btn-link" ng-click="vm.showAll($event)">
5   - <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span> Ver todos os {{::vm.articles.length}} programas
6   - </button>
7   - </header>
8   - <div>
9   - <div class="col-sm-12">
10   - <aside class="form-inline">
11   - <div class="row">
12   - <div class="col-xs-6 col-sm-7 col-md-9">
13   - <label for="articleQueryFilter" class="control-label sr-only">Filtrar programas:</label>
14   - <input id="articleQueryFilter" type="search" class="form-control" ng-model="vm.query" placeholder="Filtrar programas" aria-label="Filtrar programas" >
15   - </div>
16   -
17   - <!-- <label for="selectCategoryFilter" class="control-label sr-only">Filtrar por tema:</label>
18   - <select id="selectCategoryFilter" name="selectCategoryFilter" class="form-control" ng-model="vm.categoryFilter" ng-options="category.name for category in vm.categories track by category.slug">
19   - <option value="">-- Filtrar por tema --</option>
20   - </select> -->
21   -
22   - <div class="col-xs-6 col-sm-5 col-md-3">
23   - <label for="articleOrderByFilter" class="control-label sr-only">Ordernar por:</label>
24   - <select id="articleOrderByFilter" name="articleOrderByFilter" class="form-control pull-right" ng-model="vm.orderCriteria" ng-options="orderCriteria.label for orderCriteria in vm.orderCriteries">
25   - <option value="">-- Ordernar por: --</option>
26   - </select>
27   - </div>
28   - <!-- <div class="checkbox">
29   - <label>
30   - <input type="checkbox" ng-model="vm.reverse">
31   - Reverso
32   - </label>
33   - </div> -->
34   -
35   - <!-- <input id="articleLimitFilter" type="number" class="form-control input-sm" size="4" step="2" ng-model="vm.limitTo" aria-label="Limitar" >
36   - <label for="articleLimitFilter" class="control-label">Limite</label> -->
37   -
38   - </div>
39   - </aside>
40   - </div>
41   -
42   - <div ng-repeat="article in vm.filtredArticleList as results">
43   - <article-box article="article" class="col-xs-12 col-sm-6"></article-box>
44   - <div ng-if="$odd" class="clearfix"></div>
45   - </div>
46   - <div class="animate-repeat" ng-if="results.length == 0">
47   - Nenhum programa encontrado.
48   - </div>
  1 +<div class="article-grid">
  2 + <div ng-repeat="article in vm.articles as results">
  3 + <article-box article="article" category="article.categories[0]" class="col-xs-12 col-sm-6"></article-box>
  4 + <div ng-if="$odd" class="clearfix"></div>
49 5 </div>
50   -</article>
  6 + <div class="animate-repeat" ng-if="results.length == 0">
  7 + Nenhum programa encontrado.
  8 + </div>
  9 +</div>
... ...
src/app/components/article-grid/article-grid.scss
1 1 .article-grid {
2   - .header {
3   - position: relative;
4   - height: 40px;
5   - margin-bottom: 10px;
6   -
7   - button {
8   - position: absolute;
9   - right: 0;
10   - top: 2px;
11   - }
12   - }
13   -
14   - .form-inline {
15   - input,
16   - select {
17   - width: 100%;
18   - }
19   - }
20 2 }
... ...
src/app/components/article-service/article.service.js
... ... @@ -90,7 +90,7 @@
90 90 });
91 91 }
92 92  
93   - function searchTopics (param, cbSuccess, cbError) {
  93 + function searchTopics (params, cbSuccess, cbError) {
94 94 // Ex.: /api/v1/search/article?type=ProposalsDiscussionPlugin::Topic&query=cisternas
95 95 var url = '/api/v1/search/article';
96 96 var paramsExtended = angular.extend({
... ... @@ -98,14 +98,14 @@
98 98 'type': 'ProposalsDiscussionPlugin::Topic'
99 99 }, params);
100 100  
101   - UtilService.get(url, {params: paramsExtended).then(function(data){
  101 + UtilService.get(url, {params: paramsExtended}).then(function(data){
102 102 cbSuccess(data);
103 103 }).catch(function(error){
104 104 cbError(error);
105 105 });
106 106 }
107 107  
108   - function searchProposals (param, cbSuccess, cbError) {
  108 + function searchProposals (params, cbSuccess, cbError) {
109 109 // Ex.: /api/v1/search/article?type=ProposalsDiscussionPlugin::Proposal&query=cisternas
110 110 var url = '/api/v1/search/article';
111 111 var paramsExtended = angular.extend({
... ... @@ -113,7 +113,7 @@
113 113 'type': 'ProposalsDiscussionPlugin::Proposal'
114 114 }, params);
115 115  
116   - UtilService.get(url, {params: paramsExtended).then(function(data){
  116 + UtilService.get(url, {params: paramsExtended}).then(function(data){
117 117 cbSuccess(data);
118 118 }).catch(function(error){
119 119 cbError(error);
... ...
src/app/components/category-list/category-list.directive.js
... ... @@ -9,7 +9,7 @@
9 9 function categoryList() {
10 10  
11 11 /** @ngInject */
12   - function CategoryListController($rootScope, ArticleService, $location, $log) {
  12 + function CategoryListController($rootScope, $location, $log) {
13 13 $log.debug('CategoryListController');
14 14  
15 15 // alias
... ... @@ -17,33 +17,15 @@
17 17  
18 18 // dependencies
19 19 vm.$rootScope = $rootScope;
20   - vm.ArticleService = ArticleService;
21 20 vm.$location = $location;
22 21 vm.$log = $log;
23   - vm.defaultLimit = 6;
24 22  
25 23 // initialization
26 24 vm.init();
27 25 }
28 26  
29 27 CategoryListController.prototype.init = function() {
30   - var vm = this;
31   -
32   - vm.selectedCategory = null;
33   - vm.ArticleService.getCategories(function(categories){
34   - vm.categories = categories;
35   -
36   - });
37   -
38   - vm.search = vm.$location.search();
39   - if (vm.search && vm.search.tema) {
40   - var slug = vm.search.tema;
41   - vm.ArticleService.getCategoryBySlug(slug, function(category){
42   - vm.selectedCategory = category;
43   - }, function(error){
44   - vm.$log.error('Error when try to "getCategoryBySlug"', error);
45   - });
46   - }
  28 + // var vm = this;
47 29 };
48 30  
49 31 CategoryListController.prototype.selectCategory = function(category, $event) {
... ... @@ -66,6 +48,10 @@
66 48 var directive = {
67 49 restrict: 'E',
68 50 templateUrl: 'app/components/category-list/category-list.html',
  51 + scope: {
  52 + categories: '=',
  53 + selectedCategory: '@'
  54 + },
69 55 controller: CategoryListController,
70 56 controllerAs: 'categoryListCtrl',
71 57 bindToController: true
... ...
src/app/components/dialoga-service/dialoga.service.js
... ... @@ -6,146 +6,219 @@
6 6 .factory('DialogaService', DialogaService);
7 7  
8 8 /** @ngInject */
9   - function DialogaService($rootScope, API, ArticleService, UtilService, Slug, $log) {
  9 + function DialogaService($rootScope, $sce, API, ArticleService, UtilService, Slug, $log) {
10 10 $log.debug('DialogaService');
11 11  
12 12 var service = {
13   - getInicio: getInicio,
14   - getSobre: getSobre,
15   - getTemas: getTemas,
16   - getProgramas: getProgramas,
17   - getPropostas: getPropostas,
18   - getDuvidas: getDuvidas,
19   - buscaPrograma: buscaPrograma,
20   - buscaProposta: buscaProposta,
  13 + getHome: getHome,
  14 + getAbout: getAbout,
  15 + getThemes: getThemes,
  16 + getPrograms: getPrograms,
  17 + getProgramBySlug: getProgramBySlug,
  18 + getProgramsRandom: getProgramsRandom,
  19 + getProposals: getProposals,
  20 + getEvents: getEvents,
  21 + getQuestions: getQuestions,
  22 + searchProgram: searchProgram,
  23 + searchProposal: searchProposal,
21 24 };
22 25  
23 26 var CACHE = {};
24 27  
25 28 return service;
26 29  
27   - function getInicio (cbSuccess, cbError) {
28   - if(CACHE.hasOwnProperty('inicio')){
29   - cbSuccess(CACHE.inicio);
  30 + function getHome (cbSuccess, cbError) {
  31 + if( !!CACHE.home ){
  32 + cbSuccess(CACHE.home);
30 33 }else{
31 34 // load main content
32 35 ArticleService.getArticleById(API.articleId.home, {
33   - fields: 'id,abstract,body,categories,children,children_count,title'
34   - }, function (article){
35   - CACHE.inicio = article;
  36 + 'fields[]': ['id','abstract','body','categories','children','children_count','title','image','url']
  37 + }, function (data){
  38 + CACHE.home = data;
36 39  
37   - _pipeSetSobre(article);
38   - _pipeSetTemas(article);
39   - _pipeSetProgramas(article);
  40 + _pipeHandleYoutube(data);
  41 + _pipeHandleSlug(data);
  42 + _pipeSetAbout(data);
  43 + _pipeSetThemes(data);
  44 + _pipeSetPrograms(data);
40 45  
41   - cbSuccess(article);
  46 + cbSuccess(data);
42 47 }, cbError);
43 48 }
44 49 }
45 50  
46   - function getSobre (cbSuccess, cbError) {
47   - if(CACHE.hasOwnProperty('sobre')){
48   - cbSuccess(CACHE.sobre);
  51 + function getAbout (cbSuccess, cbError) {
  52 + if( !!CACHE.about ){
  53 + cbSuccess(CACHE.about);
49 54 }else{
50 55 // load article content
51 56 ArticleService.getArticleById(API.articleId.about, {}, function (article){
52   - CACHE.sobre = article;
  57 + CACHE.about = article;
53 58  
54   - cbSuccess(CACHE.sobre);
  59 + cbSuccess(CACHE.about);
55 60 }, cbError);
56 61 }
57 62 }
58 63  
59   - function getTemas (cbSuccess, cbError) {
60   - if(CACHE.hasOwnProperty('temas')){
61   - cbSuccess(CACHE.temas);
  64 + function getThemes (cbSuccess, cbError) {
  65 + if( !!CACHE.themes ){
  66 + cbSuccess(CACHE.themes);
62 67 }else{
63 68 // load main content
64   - getInicio(function(){
65   - if(!CACHE.hasOwnProperty('temas')){
66   - throw { name: 'NotFound', message: '"temas" is not defined. "article.categories" was handled?'};
  69 + getHome(function(){
  70 + if(!CACHE.hasOwnProperty('themes')){
  71 + throw { name: 'NotFound', message: '"themes" is not defined. "article.categories" was loaded?'};
67 72 }
68   - cbSuccess(CACHE.temas);
  73 + cbSuccess(CACHE.themes);
69 74 },cbError);
70 75 }
71 76 }
72 77  
73   - function getProgramas (cbSuccess, cbError) {
74   - if(CACHE.hasOwnProperty('programas')){
75   - cbSuccess(CACHE.programas);
  78 + function getPrograms (cbSuccess, cbError) {
  79 + if( !!CACHE.programs ){
  80 + cbSuccess(CACHE.programs);
76 81 }else{
77 82 // load main content
78   - getInicio(function(){
79   - if(!CACHE.hasOwnProperty('programas')){
80   - throw { name: 'NotFound', message: '"programas" is not defined. "article.children" was handled?'};
  83 + getHome(function(){
  84 + if(!CACHE.hasOwnProperty('programs')){
  85 + throw { name: 'NotFound', message: '"programs" is not defined. "article.children" was handled?'};
81 86 }
82   - cbSuccess(CACHE.programas);
  87 + cbSuccess(CACHE.programs);
83 88 },cbError);
84 89 }
85 90 }
86 91  
87   - function getProgramasAleatorios (cbSuccess, cbError) {
88   - // load article content
89   - UtilService.get(API.random_topics, {params: {
90   - 'fields[]': [
91   - 'id', 'title', 'slug', 'abstract', 'body', 'categories', 'setting',
92   - 'ranking_position', 'position', 'children_count', 'hits', 'votes_for',
93   - 'votes_against', 'tag_list']
94   - }}).then(function(data){
95   - cbSuccess(data);
96   - }).catch(function(error){
97   - cbError(error);
98   - });
  92 + function getProgramBySlug (slug, cbSuccess, cbError) {
  93 +
  94 + if( !CACHE.programs ){
  95 + getPrograms(_getProgramBySlug, cbError);
  96 + } else {
  97 + _getProgramBySlug();
  98 + }
  99 +
  100 + function _getProgramBySlug(){
  101 + var result = CACHE.programs.filter(function filterProgramBySlug (program) {
  102 + if(angular.equals(program.slug, slug)) {
  103 + return true;
  104 + }
  105 + return false;
  106 + });
  107 +
  108 + cbSuccess(result[0]);
  109 + }
99 110 }
100 111  
101   - function getPropostas (cbSuccess, cbError) {
102   - if(CACHE.hasOwnProperty('propostas')){
103   - cbSuccess(CACHE.propostas);
  112 + function getProgramsRandom (cbSuccess, cbError) {
  113 + getPrograms(cbSuccess, cbError);
  114 + // TODO: get endpoint for production
  115 + // if( !!CACHE.programsRandom ){
  116 + // cbSuccess(CACHE.programsRandom);
  117 + // }else{
  118 + // // load article content
  119 + // // UtilService.get(API.random_topics, {params: {
  120 + // ArticleService.getArticleById(API.articleId.home, {params: {
  121 + // 'fields[]': [
  122 + // 'id', 'title', 'slug', 'abstract', 'children_count'],
  123 + // 'content_type': 'ProposalsDiscussionPlugin::Topic'
  124 + // }}).then(function(data){
  125 + // CACHE.programsRandom = data;
  126 +
  127 + // cbSuccess(data);
  128 + // }).catch(function(error){
  129 + // cbError(error);
  130 + // });
  131 + // }
  132 + }
  133 +
  134 + function getProposals (cbSuccess, cbError) {
  135 + if( !!CACHE.proposals ){
  136 + cbSuccess(CACHE.proposals);
104 137 }else{
105 138 // load main content
106   - getInicio(function(){
107   - if(!CACHE.hasOwnProperty('propostas')){
108   - throw { name: 'NotFound', message: '"propostas" is not defined. "article.categories" was handled?'};
  139 + getHome(function(){
  140 + if(!CACHE.hasOwnProperty('proposals')){
  141 + throw { name: 'NotFound', message: '"proposals" is not defined. "article.categories" was loaded?'};
109 142 }
110   - cbSuccess(CACHE.propostas);
  143 + cbSuccess(CACHE.proposals);
111 144 },cbError);
112 145 }
113 146 }
114 147  
115   - function getDuvidas (cbSuccess, cbError) {
116   - if(CACHE.hasOwnProperty('duvidas')){
117   - cbSuccess(CACHE.duvidas);
  148 + function getEvents (cbSuccess, cbError) {
  149 + if( !!CACHE.events ){
  150 + cbSuccess(CACHE.events);
  151 + }else{
  152 + // load main content
  153 + getHome(function(){
  154 + if(!CACHE.hasOwnProperty('events')){
  155 + throw { name: 'NotFound', message: '"events" is not defined. "article.categories" was loaded?'};
  156 + }
  157 + cbSuccess(CACHE.events);
  158 + },cbError);
  159 + }
  160 + }
  161 +
  162 + function getQuestions (cbSuccess/*, cbError*/) {
  163 + if( !!CACHE.questions ){
  164 + cbSuccess(CACHE.questions);
118 165 }else{
119 166 // load content
120   - var duvidas = [];
  167 + var questions = [];
121 168  
122   - CACHE.duvidas = duvidas;
123   - cbSuccess(CACHE.duvidas);
  169 + CACHE.questions = questions;
  170 + cbSuccess(CACHE.questions);
124 171 }
125 172 }
126 173  
127   - function buscaPrograma (cbSuccess, cbError) {}
  174 + function searchProgram (cbSuccess, cbError) {}
  175 +
  176 + function searchProposal (cbSuccess, cbError) {}
  177 +
  178 + function _pipeHandleYoutube (data) {
  179 + var abstract = data.article.abstract;
  180 +
  181 + abstract = forceIframeParams(abstract);
  182 + abstract = removeStylefromIframe(abstract);
  183 +
  184 + data.article.abstract = abstract;
  185 +
  186 + data.article.abstractTrusted = $sce.trustAsHtml(abstract);
  187 + }
  188 +
  189 + function _pipeHandleSlug (data) {
  190 + // set slug to article
  191 + if(!data.article.slug){
  192 + data.article.slug = Slug.slugify(data.article.title);
  193 + }
128 194  
129   - function buscaProposta (cbSuccess, cbError) {}
  195 + // set slug to programs
  196 + for (var i = data.article.children.length - 1; i >= 0; i--) {
  197 + var program = data.article.children[i];
  198 + if(!program.slug){
  199 + program.slug = Slug.slugify(program.title);
  200 + }
  201 + }
  202 + }
130 203  
131   - function _pipeSetSobre (article) {
132   - if(!CACHE.hasOwnProperty('sobre')){
133   - CACHE.sobre = article.body;
  204 + function _pipeSetAbout (data) {
  205 + if(!CACHE.hasOwnProperty('about')){
  206 + CACHE.about = data.article.body;
134 207 }
135 208 }
136 209  
137   - function _pipeSetTemas (article) {
138   - if(!CACHE.hasOwnProperty('temas')){
139   - CACHE.temas = article.categories;
  210 + function _pipeSetThemes (data) {
  211 + if(!CACHE.hasOwnProperty('themes')){
  212 + CACHE.themes = data.article.categories;
140 213 }
141 214  
142   - _pipeCalcColors(article);
  215 + _pipeCalcColors(data);
143 216 }
144 217  
145   - function _pipeSetProgramas (article) {
146   - if(!CACHE.hasOwnProperty('programas')){
147   - CACHE.programas = article.children;
148   - CACHE.programas_count = article.children_count;
  218 + function _pipeSetPrograms (data) {
  219 + if(!CACHE.hasOwnProperty('programs')){
  220 + CACHE.programs = data.article.children;
  221 + CACHE.programs_count = data.article.children_count;
149 222 }
150 223 }
151 224  
... ... @@ -166,5 +239,52 @@
166 239 // };
167 240 }
168 241 }
  242 +
  243 + function forceIframeParams(abstract) {
  244 + var patternIframe = '<iframe src="';
  245 + var indexOfIframe = abstract.indexOf(patternIframe);
  246 +
  247 + if (indexOfIframe === -1) {
  248 + return abstract;
  249 + }
  250 +
  251 + var startSrcUrl = indexOfIframe + patternIframe.length;
  252 + var endSrcUrl = abstract.indexOf('"', startSrcUrl);
  253 + var srcUrl = abstract.substring(startSrcUrl , endSrcUrl);
  254 + var resultUrl = srcUrl;
  255 + var c = (srcUrl.indexOf('?') !== -1) ? '&' : ''; // already have url params. So, append-it
  256 +
  257 + // enable js api
  258 + if (srcUrl.indexOf('enablejsapi=1') === -1) {
  259 + resultUrl += c + 'enablejsapi=1';
  260 + c = '&'; // force to always use '&' after here
  261 + }
  262 +
  263 + // set opaque mode
  264 + if (srcUrl.indexOf('wmode=opaque') === -1) {
  265 + resultUrl += c + 'wmode=opaque';
  266 + // c = '&'; // force to always use '&' after here
  267 + }
  268 +
  269 + abstract = abstract.replace(srcUrl, resultUrl);
  270 +
  271 + return abstract;
  272 + }
  273 +
  274 + function removeStylefromIframe (abstract) {
  275 + var patternIframe = 'style="';
  276 + var indexOfIframe = abstract.indexOf('<iframe');
  277 + var indexOfStyleOnIframe = abstract.indexOf('style="', indexOfIframe);
  278 +
  279 + if (indexOfStyleOnIframe === -1) {
  280 + return abstract;
  281 + }
  282 +
  283 + var startStyleContent = indexOfStyleOnIframe + patternIframe.length;
  284 + var endStyleContent = abstract.indexOf('"', startStyleContent);
  285 + var style = abstract.substring(startStyleContent , endStyleContent);
  286 +
  287 + return abstract.replace(style, '');
  288 + }
169 289 }
170 290 })();
... ...
src/app/components/proposal-related/proposal-related.directive.js
... ... @@ -76,7 +76,7 @@
76 76 if(vm.display === 'list'){
77 77 // wait until DOM be created
78 78 vm.$timeout(function(){
79   - attachPopover.call(vm);
  79 + // attachPopover.call(vm);
80 80 }, 20);
81 81 }
82 82 }, 2000);
... ...
src/app/components/socialShare/socialShare.directive.js
... ... @@ -23,7 +23,7 @@
23 23 function SocialShareController($log) {
24 24 $log.debug('SocialShareController');
25 25  
26   - var vm = this;
  26 + // var vm = this;
27 27 }
28 28 }
29 29  
... ...
src/app/pages/inicio/inicio.controller.js
... ... @@ -7,11 +7,12 @@
7 7 .controller('InicioPageController', InicioPageController);
8 8  
9 9 /** @ngInject */
10   - function InicioPageController(DialogaService, $sce, $log) {
  10 + function InicioPageController(DialogaService, $scope, $sce, $log) {
11 11 var vm = this;
12 12  
13 13 // aliases
14 14 vm.DialogaService = DialogaService;
  15 + vm.$scope = $scope;
15 16 vm.$sce = $sce;
16 17 vm.$log = $log;
17 18  
... ... @@ -22,58 +23,95 @@
22 23 InicioPageController.prototype.init = function() {
23 24 var vm = this;
24 25  
  26 + vm.article = null;
  27 + vm.themes = null;
  28 + vm.selectedTheme = null;
  29 + vm.programs = null;
  30 + vm.filtredPrograms = null;
  31 + vm.query = null;
  32 +
25 33 vm.error = null;
26   - vm.loading = true;
27 34  
28 35 vm.loadData();
  36 + vm.attachListeners();
29 37 };
30 38  
31 39 InicioPageController.prototype.loadData = function() {
32 40 var vm = this;
33 41  
34   - vm.content = vm.DialogaService.getHomeAbstract();
35   - vm.isCached = !!vm.content;
36   -
37   - if (vm.isCached) {
38   - hideBackground(2000);
39   - }
  42 + vm.loading = true;
  43 + vm.loadingEvents = true;
  44 + vm.loadingThemes = true;
  45 + vm.loadingPrograms = true;
40 46  
  47 + // Load main content
41 48 vm.DialogaService.getHome(function(data) {
42   - vm.loading = false;
43 49 vm.article = data.article;
  50 +
  51 + if (vm.article.videoIsLoaded) {
  52 + hideBackground(2000);
  53 + }
  54 +
  55 + loadAfterHome();
  56 +
  57 + vm.loading = false;
44 58 }, function(error) {
45   - vm.$log.error('Error on getHome article.', error);
46   - vm.error = 'Erro ao carregar o conteúdo principal.';
  59 + vm.$log.error('Error on getHome.', error);
47 60 });
  61 +
  62 + function loadAfterHome () {
  63 + // Load event list
  64 + // vm.DialogaService.getEvents(function(data) {
  65 + // vm.events = data;
  66 + // vm.loadingEvents = false;
  67 + // }, function(error) {
  68 + // vm.$log.error('Error on getEvents.', error);
  69 + // });
  70 +
  71 + // Load theme list
  72 + vm.DialogaService.getThemes(function(data) {
  73 + vm.themes = data;
  74 + vm.loadingThemes = false;
  75 + }, function(error) {
  76 + vm.$log.error('Error on getThemes.', error);
  77 + });
  78 +
  79 + // Load program list
  80 + vm.DialogaService.getProgramsRandom(function(data) {
  81 + vm.programs = vm.article.children;
  82 + vm.filtredPrograms = data;
  83 + vm.loadingPrograms = false;
  84 + }, function(error) {
  85 + vm.$log.error('Error on getPrograms.', error);
  86 + });
  87 + }
  88 +
48 89 };
49 90  
50 91 InicioPageController.prototype.showVideo = function() {
51 92 var vm = this;
52 93  
53 94 // we need handle home content
54   - if (vm.isCached) {
  95 + if (vm.article.videoIsLoaded) {
55 96 hideBackground(0); // force to hide
56 97 vm.$log.debug('The content already cached. Show-it!');
57 98 return;
58 99 }
59 100  
60   - vm.content = vm.handleHomeAbstract(vm.article.abstract);
61   - vm.DialogaService.setHomeAbstract(vm.content);
62   -
63 101 // inject dependencies
64 102 injectIframeApiJs();
65 103 window.onYouTubeIframeAPIReady = window.onYouTubeIframeAPIReady || onYouTubeIframeAPIReady;
66 104 window.onYouTubePlayerReady = window.onYouTubePlayerReady || onYouTubePlayerReady;
  105 +
  106 + vm.article.videoIsLoaded = true;
67 107 };
68 108  
69   - // TODO: move this to DialogaService
70   - InicioPageController.prototype.handleHomeAbstract = function(abstract) {
  109 + InicioPageController.prototype.attachListeners = function() {
71 110 var vm = this;
72 111  
73   - abstract = forceIframeParams(abstract);
74   - abstract = removeStylefromIframe(abstract);
75   -
76   - return vm.$sce.trustAsHtml(abstract);
  112 + vm.$scope.$on('change-selectedCategory', function (selectedCategory) {
  113 + vm.selectedTheme = selectedCategory;
  114 + });
77 115 };
78 116  
79 117 function injectIframeApiJs() {
... ... @@ -104,51 +142,4 @@
104 142 angular.element($elBg).fadeOut(ms || 100);
105 143 // angular.element($elBg).hide();
106 144 }
107   -
108   - function forceIframeParams(abstract) {
109   - var patternIframe = '<iframe src="';
110   - var indexOfIframe = abstract.indexOf(patternIframe);
111   -
112   - if (indexOfIframe === -1) {
113   - return abstract;
114   - }
115   -
116   - var startSrcUrl = indexOfIframe + patternIframe.length;
117   - var endSrcUrl = abstract.indexOf('"', startSrcUrl);
118   - var srcUrl = abstract.substring(startSrcUrl , endSrcUrl);
119   - var resultUrl = srcUrl;
120   - var c = (srcUrl.indexOf('?') !== -1) ? '&' : ''; // already have url params. So, append-it
121   -
122   - // enable js api
123   - if (srcUrl.indexOf('enablejsapi=1') === -1) {
124   - resultUrl += c + 'enablejsapi=1';
125   - c = '&'; // force to always use '&' after here
126   - }
127   -
128   - // set opaque mode
129   - if (srcUrl.indexOf('wmode=opaque') === -1) {
130   - resultUrl += c + 'wmode=opaque';
131   - // c = '&'; // force to always use '&' after here
132   - }
133   -
134   - abstract = abstract.replace(srcUrl, resultUrl);
135   -
136   - return abstract;
137   - }
138   -
139   - function removeStylefromIframe (abstract) {
140   - var patternIframe = 'style="';
141   - var indexOfIframe = abstract.indexOf('<iframe');
142   - var indexOfStyleOnIframe = abstract.indexOf('style="', indexOfIframe);
143   -
144   - if (indexOfStyleOnIframe === -1) {
145   - return abstract;
146   - }
147   -
148   - var startStyleContent = indexOfStyleOnIframe + patternIframe.length;
149   - var endStyleContent = abstract.indexOf('"', startStyleContent);
150   - var style = abstract.substring(startStyleContent , endStyleContent);
151   -
152   - return abstract.replace(style, '');
153   - }
154 145 })();
... ...
src/app/pages/inicio/inicio.html
... ... @@ -6,11 +6,11 @@
6 6 <div class="video-wrapper">
7 7 <div class="video-player js-youtube">
8 8 <div class="embed-responsive embed-responsive-16by9">
9   - <div class="js-iframe" ng-show="pageInicio.content" ng-bind-html="pageInicio.content"></div>
  9 + <div class="js-iframe" ng-if="pageInicio.article.videoIsLoaded" ng-bind-html="pageInicio.article.abstractTrusted"></div>
10 10 <div class="video-background" ng-click="pageInicio.showVideo()">
11 11 <div class="video-thumbnail" aria-hidden="true" style="background-image:url(/assets/images/youtube-background.png)"></div>
12 12 <button class="video-play-button" aria-live="assertive" aria-label="Assistir o vídeo tutorial Dialoga Brasil">
13   - <svg height="100%" version="1.1" viewBox="0 0 68 48" width="100%"><path class="ytp-play-button-bg" d="m .66,37.62 c 0,0 .66,4.70 2.70,6.77 2.58,2.71 5.98,2.63 7.49,2.91 5.43,.52 23.10,.68 23.12,.68 .00,-1.3e-5 14.29,-0.02 23.81,-0.71 1.32,-0.15 4.22,-0.17 6.81,-2.89 2.03,-2.07 2.70,-6.77 2.70,-6.77 0,0 .67,-5.52 .67,-11.04 l 0,-5.17 c 0,-5.52 -0.67,-11.04 -0.67,-11.04 0,0 -0.66,-4.70 -2.70,-6.77 C 62.03,.86 59.13,.84 57.80,.69 48.28,0 34.00,0 34.00,0 33.97,0 19.69,0 10.18,.69 8.85,.84 5.95,.86 3.36,3.58 1.32,5.65 .66,10.35 .66,10.35 c 0,0 -0.55,4.50 -0.66,9.45 l 0,8.36 c .10,4.94 .66,9.45 .66,9.45 z" fill="#1f1f1e" fill-opacity="0.9"></path><path d="m 26.96,13.67 18.37,9.62 -18.37,9.55 -0.00,-19.17 z" fill="#fff"></path><path d="M 45.02,23.46 45.32,23.28 26.96,13.67 43.32,24.34 45.02,23.46 z" fill="#ccc"></path></svg>
  13 + <svg height="100%" version="1.1" viewbox="0 0 68 48" width="100%"><path class="ytp-play-button-bg" d="m .66,37.62 c 0,0 .66,4.70 2.70,6.77 2.58,2.71 5.98,2.63 7.49,2.91 5.43,.52 23.10,.68 23.12,.68 .00,-1.3e-5 14.29,-0.02 23.81,-0.71 1.32,-0.15 4.22,-0.17 6.81,-2.89 2.03,-2.07 2.70,-6.77 2.70,-6.77 0,0 .67,-5.52 .67,-11.04 l 0,-5.17 c 0,-5.52 -0.67,-11.04 -0.67,-11.04 0,0 -0.66,-4.70 -2.70,-6.77 C 62.03,.86 59.13,.84 57.80,.69 48.28,0 34.00,0 34.00,0 33.97,0 19.69,0 10.18,.69 8.85,.84 5.95,.86 3.36,3.58 1.32,5.65 .66,10.35 .66,10.35 c 0,0 -0.55,4.50 -0.66,9.45 l 0,8.36 c .10,4.94 .66,9.45 .66,9.45 z" fill="#1f1f1e" fill-opacity="0.9"></path><path d="m 26.96,13.67 18.37,9.62 -18.37,9.55 -0.00,-19.17 z" fill="#fff"></path><path d="M 45.02,23.46 45.32,23.28 26.96,13.67 43.32,24.34 45.02,23.46 z" fill="#ccc"></path></svg>
14 14 </button>
15 15 </div>
16 16 </div>
... ... @@ -22,31 +22,90 @@
22 22 </section>
23 23  
24 24 <section class="section-event">
25   - <event-list></event-list>
  25 + <div ng-if="pageInicio.events">
  26 + <event-list events="[]"></event-list>
  27 + </div>
  28 + <div ng-if="!pageInicio.events && pageInicio.loadingEvents" class="container">
  29 + <div class="row">
  30 + <div class="col-sm-12">
  31 + <div class="alert alert-info" role="alert">Carregando lista de eventos.</div>
  32 + </div>
  33 + </div>
  34 + </div>
  35 + <div ng-if="!pageInicio.events && pageInicio.eventsError" class="container">
  36 + <div class="row">
  37 + <div class="col-sm-12">
  38 + <div class="alert alert-danger" role="alert">Não foi possível carregar a lista de eventos neste momento.</div>
  39 + </div>
  40 + </div>
  41 + </div>
26 42 </section>
27 43  
28 44 <section class="section-info" ng-if="pageInicio.loading || pageInicio.error">
29 45 <div class="container">
30   - <div class="col-md-12">
31   - <div ng-if="pageInicio.loading && !pageInicio.error">
32   - <div class="alert alert-info">Carregando conteúdo...</div>
33   - </div>
34   -
35   - <div ng-if="pageInicio.error">
36   - <div class="alert alert-danger">{{pageInicio.error}}</div>
  46 + <div class="row">
  47 + <div class="col-md-12">
  48 + <div ng-if="pageInicio.loading && !pageInicio.error">
  49 + <div class="alert alert-info" role="alert">Carregando conteúdo...</div>
  50 + </div>
  51 +
  52 + <div ng-if="pageInicio.error">
  53 + <div class="alert alert-danger" role="alert">
  54 + Erro ao carregar o conteúdo principal.
  55 + </div>
  56 + </div>
37 57 </div>
38 58 </div>
39 59 </div>
40 60 </section>
41 61  
42   - <section class="section-gray section-space-up" ng-if="pageInicio.article">
  62 + <section class="section--articles section-gray section-space-up" ng-if="pageInicio.article">
43 63 <div class="container">
44 64 <div id="lista-de-programas" class="row">
45 65 <div class="col-sm-4 col-md-3">
46   - <category-list></category-list>
  66 + <div ng-if="pageInicio.themes">
  67 + <category-list categories="pageInicio.themes" selected-category="pageInicio.selectedTheme"></category-list>
  68 + </div>
  69 + <div ng-if="!pageInicio.themes && pageInicio.loadingThemes">
  70 + <div class="alert alert-info" role="alert">
  71 + Carregando temas.
  72 + </div>
  73 + </div>
  74 + <div ng-if="!pageInicio.themes && pageInicio.themesError">
  75 + <div class="alert alert-danger" role="alert">
  76 + Não foi possível carregar a lista de temas neste momento.
  77 + </div>
  78 + </div>
47 79 </div>
48 80 <div class="col-sm-8 col-md-9">
49   - <article-grid></article-grid>
  81 + <div class="row">
  82 + <header class="header">
  83 + <h2>Conheça os programas <span class="small">({{pageInicio.filtredPrograms.length}}/{{::pageInicio.programs.length}})</span></h2>
  84 + <button type="button" class="btn btn-link" ng-click="pageInicio.showAll($event)">
  85 + <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span> Ver todos os {{::pageInicio.programs.length}} programas
  86 + </button>
  87 + </header>
  88 + </div>
  89 + <div class="row">
  90 + <div class="col-xs-6 col-sm-7 col-md-9">
  91 + <label for="articleQueryFilter" class="control-label sr-only">Filtrar programas:</label>
  92 + <input id="articleQueryFilter" type="search" class="form-control" ng-model="pageInicio.query" placeholder="Filtrar programas" aria-label="Filtrar programas" >
  93 + </div>
  94 + </div>
  95 +
  96 + <div ng-if="pageInicio.programs">
  97 + <article-grid articles="pageInicio.filtredPrograms"></article-grid>
  98 + </div>
  99 + <div ng-if="!pageInicio.programs && pageInicio.loadingPrograms">
  100 + <div class="alert alert-info" role="alert">
  101 + Carregando programas.
  102 + </div>
  103 + </div>
  104 + <div ng-if="!pageInicio.programs && pageInicio.programsError">
  105 + <div class="alert alert-danger" role="alert">
  106 + Não foi possível carregar a lista de programas neste momento.
  107 + </div>
  108 + </div>
50 109 </div>
51 110 </div>
52 111 </div>
... ...
src/app/pages/inicio/inicio.scss
1 1 .page--inicio {
2 2 margin-top: 20px;
  3 +
  4 + .section--articles {
  5 +
  6 + .header {
  7 + position: relative;
  8 + height: 40px;
  9 + margin-bottom: 10px;
  10 +
  11 + button {
  12 + position: absolute;
  13 + right: 0;
  14 + top: 2px;
  15 + }
  16 + }
  17 +
  18 + .form-inline {
  19 + input,
  20 + select {
  21 + width: 100%;
  22 + }
  23 + }
  24 + }
3 25 }
4 26  
5 27 .section-gray {
... ...
src/assets/images/icons/sprite.png

104 KB | W: | H:

104 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin