Avalia+

De MSTECH wiki
Ir para: navegação, pesquisa

Descrição

Descrever nesta área o que é o produto, quais as necessidades de negócio pretende atender, a quem se destina.

Funcionalidades de Ouro

Nesta seção, insira 3 ou 4 funcionalidades que diferenciam e destacam o produto. De preferência coloque apenas os nomes das funcionalidades

Link do Product Backlog

Nesta seção, insira o link do Product Backlog do produto

Arquitetura

Avalia+3.png

Arquitetura BD

Imagem da modelagem de tabelas

Arquitetura Front-End

O Avalia+ não se utiliza de rotas virtuais do ArgularJS, diferentemente de uma aplicação SPA[1]).

Todos os componentes (construídos internamente) do Avalia+ (controllers, directives, filters, services e etc) são construídos baseados no pattern IIFE[2]

Estrutura funcional

- Pastas (negrito)
- Arquivos (negrito + itálico)

  • css
    • vendor
      • angular-motion
        • modules - animações utilizaveis com angularJS ng-animate
      • awesome-bootstrap-checkbox.css - customizações de layout realizadas sobre os campos checkbox/radio do html
      • bootstrap.css - franework
      • font-awesome.css - customização de fontes para bootstrap
    • prova.css - estilos para gerar .pdf da prova
    • style.scss - estilos gerais do sistema
  • fonts - fontes awesome/material
  • images - imagens gerais do sistema/manual do sistema em .pdf
  • js
    • angular
      • controllers - rotas 'físicas' asp.NET
      • directives
        • _bundle - todas as diretivas utilizadas no sistema
        • directives.js - modulo centralizador de diretivas
      • filters
        • _bundle - todos os filtros utilizados no sistema
      • models - todos os 'models' são serviços que são construídos com base na utilização dos serviços nativos '$http/$resource'
      • services
        • _bundle - todos os serviços utilizados no sistema
        • ApiSetting.js - config. Api
        • services.js - modulo centralizador de serviços
        • authenticationinterceptor.service.js - modulo responsável por interceptar todas requisições realizadas sobre AJAX
    • vendor
      • angular - framework AngularJS
      • compressor - realiza a compressão de arquivos de imagem (.jpg ideal) utilizando canvas do html
      • datepicker - plugin para exibição e utilização de calendário
      • highcharts - plugin para exibição gráficos
      • redactor - plugin editor de textos
      • resumable - plugin para realizar uploads com possibilidade de pause
      • bootstrap-3.2.0.js
      • jquery-2.1.1.js
      • jquery-ui.js
      • mathJax.js - framework para exibição de formulas matemáticas complexas através de LaTeX, MathML[3]
      • moment.js - plugin para formatação de datas
  • tests

Controllers

Todos os controllers AngularJS (construídos internamente) são baseados em:

- getter

  • na maioria dos controllers é injetado os módulos base (centralizadores) ['services', 'filters', 'directives]

      angular.module('appMain', ['services', 'filters', 'directives']);
   

- setter

  • nome é baseado no prefix + suffix : [nome da View asp.NET] + ["Controller"]

      angular.module('appMain').controller("FormAbsenceReasonController", FormAbsenceReasonController);

      function FormAbsenceReasonController() {};
  

- injector

  • realiza as injeções de dependências
     FormAbsenceReasonController.$inject = ['$scope', '$rootScope', '$window', '$notification', '$util', 'AbsenceReasonModel'];
  

- instanciar function no escopo

  • funções que são criadas e atribuídas ao escopo angular devem possuir um nome para facilitar o rastreamento de erros no console. Funções anônimas atribuídas diretamente ao escopo do Angular perdem a rastreabilidade em determinados casos.
  • funções atribuídas ao escopo ficam visíveis através dos $scopes do angular, algumas pessoas preferem utilizar funções no escopo se realmente for necessário seu uso na view (.html), e optam por deixa-las privadas (não atribuídas ao escopo angular).
  • se for implementado o uso de testes unitários devido ao ciclo de vida do angular o Jasmine[4] só consegue enxergar funções públicas (presentes no escopo do angular), recomenda-se cautela quando ao uso de funções privadas em soluções angular.
     //função publica: para acesso no escopo do angularJS 
     $scope.minhaFuncPublic = function __minhaFuncPublic() { };

     //função publica: para acesso no escopo do angularJS, porém anônima
     $scope.minhaFuncPublicAnonymous = function () { };

     //função privada: sem acesso no escopo do angularJS 
     function minhaFunc() { };
  

Exemplo controller AngularJS

- arquivo: formAbsenceReasonController.js

/**
 * function Cadastro/Edição Absence Reason Controller
 * @namespace Controller
 * @author Julio Cesar da Silva - 02/03/2016
 */
(function (angular, $) {

    'use strict';

    //~SETTER
    angular
        .module('appMain', ['services', 'filters', 'directives']);
    
    //~GETTER
    angular
        .module('appMain')
        .controller("FormAbsenceReasonController", FormAbsenceReasonController);
    
    FormAbsenceReasonController.$inject = ['$scope', '$rootScope', '$window', '$notification', '$util', 'AbsenceReasonModel'];

    function FormAbsenceReasonController($scope, $rootScope, $window, $notification, $util, AbsenceReasonModel) {

        $scope.params = $util.getUrlParams();
        $scope.absenceReason = { Description: undefined };

        function Init() {

            $notification.clear();
        
            if ($scope.params.Id !== undefined) {

                AbsenceReasonModel.findSimple({ Id: $scope.params.Id }, function (result) {

                    if (result.success) {
                        $scope.absenceReason = result.absenceReason;
                    }
                    else {
                        $notification[result.type ? result.type : 'error'](result.message);
                    }
                });
            }  
        };


        $scope.setNewDefault = function setNewDefault() {
            if (!$scope.absenceReason.IsDefault) {
                angular.element('#modal').modal('show');
            }
            $scope.absenceReason.IsDefault = true;
        };
        
        $scope.salvar = function __salvar() {

            if ($scope.verifica()) {

                AbsenceReasonModel.save($scope.absenceReason, function (result) {

                    if (result.success) {
                        $notification.success(result.message);
                        $window.location.href = '/AbsenceReason/List';
                    }
                    else {
                        $notification[result.type ? result.type : 'error'](result.message);
                    }                  
                }); 
            }
        };
        
        $scope.voltar = function __voltar() {
            $window.location.href = '/AbsenceReason/List';
        };
            
        $scope.verifica = function __verifica() {

            if (!$scope.absenceReason.Description) {
                $notification.alert('O campo "Descrição" é obrigatório.');    
                angular.element('#description').focus();
                return false;
            }
            return true;
        };

        Init();
    };

})(angular, jQuery);

- arquivo: ~\AbsenceReason\Form.html

<!DOCTYPE html>
<html data-ng-app="appMain">
   <head>
       <meta charset="utf-8" />
       <title>FormAbsenceReason</title>
   </head>
   <body>
      <div class="wellCustom" data-ng-controller="FormAbsenceReasonController">

      </div>
   </body>
</html>  

Directives

Quase todas as diretivas ficam centralizadas no module directives, com exceção de algumas third party (tooltip, popover e etc).

A vantagem de adotar um modulo centralizador é que as diretivas que são injetadas são somente aquelas carregadas (arquivo .js) pelo BunfleConfig.cs.


alert

dependência: ../services/_bundle/notification/notification.js

Composto por 2 diretivas:

  • alert - responsável por 'vigiar' o service $notification e criar/excluir uma nova notificação visual (html).
  • autoClose - responsável por 'empilhar' as notificações em chamadas assíncronas e remover no término do tempo de permanência na pilha.

- exemplo:

 
   <alert></alert>


checkbox-group

Utiliza um model para armazenar uma lista de checkbox selecionados

- exemplo:

    <div data-ng-repeat="($indexPeriodo, periodo) in periodoCurso.lista track by $indexPeriodo">
        <input id="checkbox_{{$indexPeriodo}}" type="checkbox" checklist-model="periodoCurso.selecionados" checklist-value="periodo" />
        <label for="checkbox_{{$indexPeriodo}}">{{periodo.Description}}</label>
    </div>


collapse

Realiza o controle de collapse (bootstrap) em elementos de um ng-repeat. Utilizado no sistema somente /Parameter

- exemplo:

    <div class="accPadrao" ng-model="grupos" data-bs-collapse>
        <div class="cards" ng-repeat="(catIndex,category) in categories track by catIndex">
           <div class="tituloAcc" data-bs-collapse-toggle>
               <h4>
                  {{category.Description}}
                  <i class="material-icons">{{ grupos == $index ? 'keyboard_arrow_up' : 'keyboard_arrow_down' }}</i>
               </h4>
           </div>
           <div class="panel-collapse" data-bs-collapse-target>
             conteúdo aqui
           </div>
        </div>
    </div>


datepicker-directive

Realiza o controle do plugin datepicker no escopo do angularJS

dependência: vendor/datepicker.js

- exemplo:

   <input id="dateStart" type="text" placeholder="Data de Início" data-ng-model="dateStart" datepicker/>


fieldinteger

Permite somente a entrada de caracteres numéricos.

- exemplo:

   <input type="text" data-ng-model="idade" fieldinteger />


highcharts-ng

Realiza a manipulação do plugin.

- exemplo:

   <highchart class="chart" config="chart"></highchart>


item-brief

Mostra o resumo detalhado de um item. (Obrigatório id do item)

- exemplo:

   <item-brief item-id="{{item.Id}}" can-print="false"></item-brief>


menu

Controla e constrói o menu do sistema. (localizado na master page)

- exemplo:

   <div menu user='@{Html.RenderAction("NomeUsuarioLogado","Layout");}' system='@ViewBag.Title'></div>


modal

Constrói uma modal. Utiliza-se da diretiva nativa ng-transclude para obter html específico, obedece ao escopo pai do 'controller' (escopo público)

Caso necessário customização das características da modal, utilizar convencional do bootstrap sem a directiva.

- exemplo:

   <modal id="cancelModal" modal-title="<p>Deseja realmente sair?</p>">
       <div class="container-fluid">
          <div class="row">
	     <div class="col-sm-12 text-right">
	        <button type="button" class="btnPadrao" ng-click="cancel();">Sim</button>
		<button type="button" class="btnCancelar2" data-dismiss="modal">Não</button>
	     </div>
	  </div>
	</div>
   </modal>


modal-alert

Notificações internas ao escopo da modal. (Necessário construir no controller objeto de notificações)

- exemplo:

   <modal-alert notification="notification.objNotification"></modal-alert>


ng-change-file

Chamada de callback quando input['file'] sofre uma alteração. Utilizável para realização de upload de arquivos dentro do escopo do controller.

- exemplo:

   <input id="fileInport" type="file" data-ng-change-file="upload">


ng-title

Mostrar title em options gerador pela diretiva nativa ng-options na tag <select>

- exemplo:

   
   <script>
       $scope.pessoas.lista = [{Id: 1, Description:'João'}, {Id: 2, Description:'Paulo'}, {Id: 3, Description:'Ana'}, {Id: 4, Description:'Mayra'}];
   </script>

   <select class="form-control"
        ng-options="pessoa as pessoa.Description for pessoa in pessoas.lista"
        ng-title="pessoas.lista"
        ng-title-propertie="Description"
        ng-title-index="1"
        ng-title-selected>
        <option value="">--Selecione--</option>
   </select>


ng-show-loading

Mostra/oculta html de loading. Utilizado dentro do template da diretiva /directives/_bundle/preloading/preloading.js

- exemplo:

   <div id="preloading" ng-show-loading class="ng-cloak loading-box"><label>{{message}}</label></div>


notification-filter

Descontinuada... Os filtros do sistema não seguem um mesmo padrão de construção nos controles, o que torna a diretiva dispensável


page

Realiza o controle da paginação.

dependência: "services/_bundle/pager/service.js" necessário injeção de dependência no controller - $pager

Há 2 formas de indicar 'paginador':

  • atributo "pager" funciona com objetos do escopo bind-two-way do angular, passagem de vários níveis de objeto
  • atributo "varkey" funciona com somente 1 nível de objeto

- exemplo 1:

   <page method="getUploadQueueStatus()" 
         pager="pagerUploadQueue.paginate" 
         total-pages="{{pagerUploadQueue.pages}}" 
         total-itens="{{pagerUploadQueue.totalItens}}" 
         page-size="pagerUploadQueue.pageSize" 
         data-arr-page-size="[10,20,30,40,50,100]"></page>

- exemplo 2:

   <page method="Paginate()" 
         varkey="paginate " 
         total-pages="{{pages}}" 
         total-itens="{{totalItens}}" 
         page-size="pageSize" 
         data-arr-page-size="[10,20,30,40,50,100]"></page>

- exemplo no controller

     $scope.paginate = $pager(ReportCorrectionModel.getDres);
     $scope.totalItens = 0;
     $scope.pages = 0;
     $scope.pageSize = 10;
     $scope.message = false;
     $scope.listResult = null;

     $scope.search = function __search() {
          if (!validateDate() || !validate()) return;
	     $scope.pages = 0;
	     $scope.totalItens = 0;
	     $scope.paginate.indexPage(0);
	     $scope.pageSize = $scope.paginate.getPageSize();
	     $scope.searcheableFilter = angular.copy($scope.filters);
	     Paginate();
     };
     
     function Paginate() { 
         $scope.paginate.paginate($scope.searcheableFilter).then(function (result) {
             if (result.success) {
		if (result.lista.length > 0) {
		    $scope.paginate.nextPage();
		    $scope.listResult = result.lista;
		    $scope.QuantidadeTotal = result.QuantidadeTotal;
		    if (!$scope.pages > 0) {
		        $scope.pages = $scope.paginate.totalPages();
		        $scope.totalItens = $scope.paginate.totalItens();
		    }
		} else {
		      $scope.message = true;
		      $scope.listResult = null;
		}
              }
	      else {
		  $notification[result.type ? result.type : 'error'](result.message);
	      }
       }, function () {
              $scope.message = true;
	       $scope.listResult = null;
       });
   };
   $scope.Paginate = Paginate;


tooltip/popover

Responsável por construir as tooltips/popovers do sistema:

  • Para utilização de popover há dependência da tooltip - directives/_bundle/popover/tooltip.js
  • directives/_bundle/popover/helpers/dimensions.js
  • css/vendor/angular-motion/**.css, aplica as animações

- exemplo popover:

   <!-- utilização de popover no html-->
   <button class="btnMais"
           type="button"
           data-ng-click="setMenu(item.Item.ItemId, item.Item.LastVersion, item.Item.BaseTextId)"
           data-placement="top" data-trigger="focus"
           data-custom-class="itemListPopover"
           data-template="Assets/js/angular/controllers/item/listItemMenu.html"
           data-animation="popover-fade"
           data-container="body"
           data-bs-popover="popovermenu">
           <i class="material-icons">view_list</i>
   </button>

   <!-- template listItemMenu.html-->
   <div class="popover" tabindex="-1" ng-show="content">
   <div class="arrow"></div>
      <div class="popover-content">
          <ul class="listaPopover">
             <li>
		 <i class="material-icons">create</i>
		 <a href="javascript:void(0)" ng-click="popovermenu.editar(popovermenu.id); $hide()">Editar</a>
	     </li>
	     <li ng-hide="item.Item.ItemNarrated" ng-click="popovermenu.addItem(popovermenu.id); $hide()">
		 <i class="material-icons">add</i>
		 <a href="javascript:void(0)">Adicionar Item</a>
	     </li>
	     <li ng-click="popovermenu.excluir(popovermenu.id); $hide()">
		 <i class="material-icons">close</i>
		 <a href="javascript:void(0)">Excluir</a>
	     </li>
          </ul>
      </div>
   </div>
    
   //utilização no controller
   $scope.popovermenu = {
	title: "empty",
	content: "empty",
	id: undefined,
	lastVersion: undefined,
        visualizar: visualizarCallback, //function
        editar: editarCallback, //function
	excluir: excluirCallback, //function
	addItem: addItemCallback, //function
   };

- exemplo tooltip com title:

     <button type="button"
             class="btnPadrao"
             data-btn-checkbox=""
             data-btn-checkbox-true="1"
             data-btn-checkbox-false="0"
             data-trigger="hover"
             data-type="success"
             data-title="Aqui vai a descrição do que esse elemento representa."
             data-placement="top"
             data-container="body"
             data-bs-tooltip>
            <i class="material-icons">add</i>
      </button>

- exemplo tooltip com template:

    
    <!-- Utilização de tooltip com template -->
    <div style="cursor:pointer; right: 15px;"
         data-trigger="hover"
         data-type="success"
         data-template="Assets/js/angular/controllers/test/currentFiltersDiscipline.html"
         data-placement="bottom"
         data-animation="am-fade"
         data-container="body"
         data-bs-tooltip
         class="notificationFilter">{{popoverFiltersDisciplines.selecteds.length}}
    </div>


    <!-- Utilização de tooltip com template -->
    <div class="tooltip in">
        <div class="tooltip-inner html-bind-trusted imgResponsive">
            <div data-ng-if="popoverFiltersDisciplines.selecteds.length!=0">Filtros selecionados</div>
            <hr data-ng-if="popoverFiltersDisciplines.selecteds.length!=0" />
            <ul style="list-style:none; padding: 0px 0px 0px 0px;">
                <li data-ng-repeat="($index, filter) in popoverFiltersDisciplines.selecteds track by $index" style="margin: 10px 0px 0px 0px">
                    <i class="material-icons">check</i>  {{filter.Description}}
                </li>
            </ul>
            <span data-ng-if="popoverFiltersDisciplines.selecteds.length==0">Nenhum filtro selecionado</span>
        </div>
    </div>


preloading

Indica que há requisições Ajax em progresso no sistema. Trabalha baseando-se no service $httpTransform presente no arquivo /service/authenticationinterceptor.service.js

- exemplo:

    <preloading message="Carregando..."></preloading>

radio-select

Seleção de radio.

- exemplo:

    <div radio-select 
         radiolist="situationList" 
         radioselected="selectedObjSituation" 
         custom-class="radio-inline" 
         style="margin: 0 -84px;">
    </div>

rating

Rating de dificuldades do sistema.

- exemplo:

   <div rating-directive 
        id="dificuldade" 
        list="dificuldade.lista" 
        difficulty="dificuldade.objDificuldade" 
        lock="false">
   </div>

redactor-directive

Controlar o plugin redactor.js através de uma directiva angularJS.

  • images - model que armazena os ids dos arquivos utilizados dentro do redactor
  • model - armazena o texto html gerado pelo redactor
  • tipo - indica para qual campo (tabela) o arquivo presente no redactor pertence
  • plugins - foram criados plugins internos para o redactor, veja: vendor/redactor

- exemplo:

    <textarea redactor
              id="textoBase"
              name="textoBase" 
              class="form-control" 
              images="textobase.Files" 
              data-ng-model="textobase.Description" 
              tipo="@((Byte)EnumFileType.BaseText)"> 
    </textarea>

report-filters

Filtros laterais para relatórios devido a 3 tela utilizarem a mesma sequência de filtros eles foram transformados em diretiva

- exemplo:

    <report-filters filters="filters" global="global"></report-filters>

tags-input

Cria um campo do tipo tags

- exemplo:

   <!-- elemento -->
   <tags-input ng-model="tags">
   </tags-input>

   //formato aceito
   $scope.tags = [{ text: 'just' }, { text: 'some' }, { text: 'cool' }];

uploader

Realiza o upload de arquivos.

  • upload.js - realiza o upload
  • uploader.js - verifica as alterações do input['file']

- exemplo:

   <div upload
        type="File" 
        trash="true" 
        placeholder="um arquivo" 
        callback="fileUploadSuccess" 
        component="modelFile">
   </div>

writemaths

Mostra o preview das fórmulas matemáticas LaTex digitadas no plugin redactor.

- exemplo:

   <div writemaths position="center top" previewposition="center bottom">
        <textarea redactor
                  id="textoBase" 
                  name="textoBase" 
                  class="form-control" 
                  images="textobase.Files" 
                  ng-model="textobase.Description" 
                  tipo="@((Byte)EnumFileType.BaseText)"> 
         </textarea>
   </div>

Filters

Filtros são a maneira mais dinâmica de formatar dados na dinâmica bind do angular.

minimize

Aplica reticências em um bind a partir do length indicado

  • recomenda-se utilização de tooltip para exibição do texto na integra.

- exemplo:

    
    $scope.meuTexto = "Um texto que extremamente longo pode ser minificado";

   <div>
      {{meuTexto | minimize:20}}
   </div>

   //resultado seria
   "Um texto que extrema..."

moment

Formatador de dadas utilizando-se do plugin moment.

- exemplo para formato ISO 8601

    
    $scope.createDate = "2016/01/01";

   <div>
      {{createDate | moment:"DD/MM/YYYY":true}}
   </div>

   //resultado seria
   "01/01/2016"

- exemplo para formato /date()/json -> /Date(1224043200000)/

    
    $scope.createDate = new Date();

   <div>
      {{createDate | moment:"DD/MM/YYYY"}}
   </div>

   //resultado seria
   "01/01/2016"

trustedHtml

Converte html não confiável para confiável, utilizado em locais com ng-bind-html

- exemplo:

    
   $scope.meuHtml = "<div>Meu texto</div>";

   <div ng-bind-html="meuHtml | trustedHtml"></div>

   //resultado seria, sem o filtro o bind daria erro de trust
   "Meu texto"

capitalize

Converte a 1ª letra em ToUpperCase </b>

- exemplo:

    
   $scope.label= "código";

   <div> {{label | capitalize}}</div>

   //resultado seria: "Código"

between

Utilizado na diretiva de paginação do sistema.

changeBlankSpace

Realiza a conversão de caracteres de espaçamento nas transações i/o do redactor. Troca os caracteres de espaçamento de \s para  . Assim os espaços em branco são respeitados no ng-bind

- exemplo:

    
   <div ng-bind-html="(abstract.textbase | changeBlankSpace) | trustedHtml"></div>

tagToString

Quando um texto base possuí somente imagens o filtro retorna uma string indicando <somente imagem>

- exemplo:

    
    {{ itens.Statement | tagToString }}

Models

A camada de comunicação do sistema, os models são mapeados segundo os controllers presentes no asp.Net, são serviços que são injetados nos controllers (angularjs) que irão interagir com 1 ou mais controller (asp.Net). No Avalia+ o serviço foi contruído com o componente nativo $resource. Como ele vem sendo utilizado desde o começo resolveu adota-lo como padrão. No entanto, uma possível futura melhoria ou abordagem seria interessante fazer o uso de $http. -exemplo:

     
    /* 
     * File-Model
     */
    (function () {
	angular.module('services').factory('FileModel', ['$resource', function ($resource) {

		// Model
		var model = {

			'uploadFile': {
				method: 'POST',
				url: base_url('File/UploadFile')
			},
			'upload': {
				method: 'POST',
				url: base_url('File/Upload')
			},
			'delete': {
				method: 'POST',
				url: base_url('File/LogicalDelete')
			},
			'searchUploadedFiles': {
			    method: 'GET',
			    url: base_url('File/SearchUploadedFiles')
			},
			'existsLinkedFiles': {
			    method: 'GET',
			    url: base_url('File/ExistsLinkedFiles')
			},
			'checkFileExists': {
			    method: 'GET',
			    url: base_url('File/CheckFileExists')
			},
			'checkFilePathExists': {
			    method: 'GET',
			    url: base_url('File/CheckFilePathExists')
			}
		};

		// Retorna o serviço       
		return $resource('', {}, model);

	}]);
   })();

Services

Serviços básicos do sistema.

notification

Controla a pilha de notificações do sistema, pilha que é utilizada pela diretiva alert.js.

-exemplo:

    
    <!-- html com a diretiva alert-->
    <alert></alert>


    (function (angular, $) {

        'use strict';

        //~SETTER
        angular
            .module('appMain', ['services', 'filters', 'directives']);
    
        //~GETTER
        angular
            .module('appMain')
            .controller("FormController", FormController);
    
        FormController.$inject = ['$scope', '$notification'];

        function FormController($scope, $notification) {
            $notification.alert('minha mensagem aqui.');
        };

   })(angular, jQuery);

pager

Controla a paginação utilizada no sistema. Dependente da diretiva page.js.

Há duas maneiras de indicar para a diretiva quem é a instancia que controla a paginação:

  • {object} pager="paginate" recebe a instância do $pager $scope, exemplo -> $scope.nivel1.nivel2.paginate
  • {string} varkey="paginate" recebe o nome da instância presente no $parent (Só funciona para objetos de 1 único nivel no $scope, exemplo -> $scope['paginate'])

-exemplo:

    
    <!-- html com a diretiva page -->
    <page method="search()" 
          pager="paginate" 
          total-pages="{{pages}}" 
          total-itens="{{totalItens}}" 
          page-size="pageSize" 
          data-arr-page-size="[10,20,30,40,50,100]"></page>


    (function (angular, $) {

        'use strict';

        //~SETTER
        angular
            .module('appMain', ['services', 'filters', 'directives']);
    
        //~GETTER
        angular
            .module('appMain')
            .controller("FormController", FormController);
    
        FormController.$inject = ['$scope', '$pager', 'SkillModel'];

        function FormController($scope, $pager, SkillModel) {
            
             $scope.paginate = $pager(SkillModel.searchByMatrix); //deve receber o service $resource
             $scope.message = false;
             $scope.pages = 0;
	     $scope.totalItens = 0;
	     $scope.pageSize = 10;
        };

   })(angular, jQuery);

util

Centralizador de utilidades do sistema, inclusive a function responsável por obter os parâmetros presente na query string da url

-exemplo:


    (function (angular, $) {

        'use strict';

        //~SETTER
        angular
            .module('appMain', ['services', 'filters', 'directives']);
    
        //~GETTER
        angular
            .module('appMain')
            .controller("FormController", FormController);
    
        FormController.$inject = ['$scope', '$util'];

        function FormController($scope, $util) {
            
            $scope.params = $util.getUrlParams();
        };

   })(angular, jQuery);

ApiSetting

Responsável por configurar requisições de comunicação com API. Vide utilização no service de interceptação de requisições

authenticationinterceptor.service

Todas as requisições (request/response/error) partindo dos componentes nativos $resource/$http serão interceptadas antes de seguir o fluxo normal client/server/client.

  • $httpTransform -> serviço presente no interceptor responsável por contabilizar a pilha de requisições ngShowLoading.js/preloading.js utilizam-se desse serviço para mostrar o loader do sistema.
  • Para controllers (angularJS) que não se comunicam com API basta não configurar o service $ApiSetting
  • Para controllers (angularJS) que se comunicam com APi segue abaixo o exemplo de como config. o service

-examplo:

    
     (function (angular, $) {

	'use strict';

	//~SETTER
	angular
		.module('appMain', ['services', 'filters', 'directives']);

	//~GETTER
	angular
	    .module('appMain')
	    .controller("CorrectionController", CorrectionController)
            .config($config);

	CorrectionController.$inject = ['$scope'];
	$config.$inject = ['$apiSettingConfigProvider'];

   
	function $config($apiSettingConfigProvider) {
	    var params = $apiSettingConfigProvider.getUrlParams();
	    $apiSettingConfigProvider.setUrlMethodExcluded("GetAuthorize");
	    $apiSettingConfigProvider.setUrlAuthentication(base_url("/MeuControllerASPNET/GetAuthorize"));
	};

	
	function CorrectionController($scope) {
        }

     })(angular, jQuery);

Versões dos frameworks

Framework versão customizado p/ necessidade interna Ref.
angularJS 1.4.9
não
https://angularjs.org/
compressor 0.1
sim
Mstech
datepicker 2012
sim
http://www.eyecon.ro/bootstrap-datepicker
highcharts 4.0.4
não
http://www.highcharts.com/
redactor 10.2.5
sim
https://imperavi.com/redactor/
resumable x.x
não
http://github.com/23/resumable.js
bootstrap 3.2.0
não
http://getbootstrap.com/
jquery 2.1.1
não
https://jquery.com/
jqueryui 1.10.3
não
http://jqueryui.com
mathJax x.x
não
https://www.mathjax.org/
moment 2.10.6
não
http://momentjs.com/

Estrutura de pastas


├───css
│   │   prova.css
│   │   style.css
│   │   style.css.map
│   │   style.min.css
│   │   style.scss
│   │   
│   ├───vendor
│   │   │   awesome-bootstrap-checkbox.css
│   │   │   bootstrap.css
│   │   │   font-awesome.css
│   │   │   
│   │   └───angular-motion
│   │       │   angular-motion.css
│   │       │   
│   │       └───modules
│   │               collapse.css
│   │               fade-and-slide.css
│   │               fade.css
│   │               flip.css
│   │               menu.css
│   │               popover-fade.css
│   │               
│   └───_bundle
│           angular.css
│           
├───fonts
│       
├───images
│
├───js
│   ├───angular
│   │   ├───controllers
│   │   │   ├───absenceReason
│   │   │   │       formAbsenceReasonController.js
│   │   │   │       listAbsenceReasonController.js
│   │   │   │       
│   │   │   ├───adherence
│   │   │   │       adherenceController.js
│   │   │   │       
│   │   │   ├───answerSheet
│   │   │   │       answerSheetLotController.js
│   │   │   │       answerSheetStudentController.js
│   │   │   │       batchDetailsController.js
│   │   │   │       customTooltip.html
│   │   │   │       schoolLotMenu.html
│   │   │   │       testLotMenu.html
│   │   │   │       
│   │   │   ├───cognitiveCompetence
│   │   │   │       formCognitiveCompetenceController.js
│   │   │   │       listCognitiveCompetenceController.js
│   │   │   │       
│   │   │   ├───correction
│   │   │   │       correctionController.js
│   │   │   │       correctionResultController.js
│   │   │   │       
│   │   │   ├───correlatedSkill
│   │   │   │       formCorrelatedSkillController.js
│   │   │   │       
│   │   │   ├───discipline
│   │   │   │       formDisciplineController.js
│   │   │   │       listDisciplineController.js
│   │   │   │       
│   │   │   ├───evaluationMatrix
│   │   │   │       evaluationMatrixController.js
│   │   │   │       evaluationMatrixListController.js
│   │   │   │       
│   │   │   ├───file
│   │   │   │       fileController.js
│   │   │   │       fileMenu.html
│   │   │   │       
│   │   │   ├───home
│   │   │   │       homeController.js
│   │   │   │       
│   │   │   ├───item
│   │   │   │       formItemController.js
│   │   │   │       listItemController.js
│   │   │   │       listItemMenu.html
│   │   │   │       
│   │   │   ├───itemLevel
│   │   │   │       formItemLevelController.js
│   │   │   │       listItemLevelController.js
│   │   │   │       
│   │   │   ├───itemType
│   │   │   │       itemTypeFormController.js
│   │   │   │       itemTypeListController.js
│   │   │   │       
│   │   │   ├───modelEvaluationMatrix
│   │   │   │       modelEvaluationMatrixController.js
│   │   │   │       modelEvaluationMatrixListController.js
│   │   │   │       
│   │   │   ├───modelTest
│   │   │   │       modelTestController.js
│   │   │   │       modelTestListController.js
│   │   │   │       
│   │   │   ├───parameter
│   │   │   │       parameterController.js
│   │   │   │       parameterMenu.html
│   │   │   │       parameterVersionableMenu.html
│   │   │   │       
│   │   │   ├───performanceLevel
│   │   │   │       formPerformanceLevelController.js
│   │   │   │       listPerformanceLevelController.js
│   │   │   │       
│   │   │   ├───reportAnswerSheet
│   │   │   │       reportAnswerSheetDREController.js
│   │   │   │       reportAnswerSheetFilesController.js
│   │   │   │       reportAnswerSheetSchoolController.js
│   │   │   │       
│   │   │   ├───reportCorrection
│   │   │   │       reportClasseController.js
│   │   │   │       reportDREController.js
│   │   │   │       reportSchoolController.js
│   │   │   │       reportStudentController.js
│   │   │   │       
│   │   │   ├───reportItem
│   │   │   │       reportItemController.js
│   │   │   │       
│   │   │   ├───reportTest
│   │   │   │       graphicPerformanceSchoolController.js
│   │   │   │       performanceItemController.js
│   │   │   │       performanceSchoolController.js
│   │   │   │       performanceSkillController.js
│   │   │   │       
│   │   │   ├───test
│   │   │   │       indexRequestRevokeMenu.html
│   │   │   │       menu-test-import-tpl.html
│   │   │   │       testAdministrateController.js
│   │   │   │       testController.js
│   │   │   │       testImportController.js
│   │   │   │       testListController.js
│   │   │   │       testListMenu.html
│   │   │   │       testReportController.js
│   │   │   │       testRequestRevokeController.js
│   │   │   │       testResponsesController.js
│   │   │   │       testRevokeController.js
│   │   │   │       
│   │   │   └───testType
│   │   │           formTestTypeController.js
│   │   │           listTestTypeController.js
│   │   │           
│   │   ├───directives
│   │   │   │   directives.js
│   │   │   │   
│   │   │   └───_bundle
│   │   │       ├───alert
│   │   │       │       alert.css
│   │   │       │       alert.js
│   │   │       │       
│   │   │       ├───checkbox-group
│   │   │       │       ckeckbox-group.js
│   │   │       │       
│   │   │       ├───collapse
│   │   │       │       collapse.js
│   │   │       │       
│   │   │       ├───datepicker
│   │   │       │       datepicker-directive.js
│   │   │       │       
│   │   │       ├───fieldinteger
│   │   │       │       fieldinteger.js
│   │   │       │       
│   │   │       ├───highcharts
│   │   │       │       highcharts-ng.js
│   │   │       │       
│   │   │       ├───item-brief
│   │   │       │       item-brief.html
│   │   │       │       item-brief.js
│   │   │       │       
│   │   │       ├───menu
│   │   │       │       menu.html
│   │   │       │       menu.js
│   │   │       │       sitemas.html
│   │   │       │       
│   │   │       ├───modal
│   │   │       │       modal.js
│   │   │       │       
│   │   │       ├───modal-alert
│   │   │       │       modal-alert.js
│   │   │       │       
│   │   │       ├───ng-change-file
│   │   │       │       ng-change-file.js
│   │   │       │       
│   │   │       ├───ng-title
│   │   │       │       ng-title.js
│   │   │       │       
│   │   │       ├───ngShowLoading
│   │   │       │       ngShowLoading.js
│   │   │       │       
│   │   │       ├───notification-filter
│   │   │       │       notification.filter.js
│   │   │       │       
│   │   │       ├───page
│   │   │       │       page.css
│   │   │       │       page.js
│   │   │       │       
│   │   │       ├───popover
│   │   │       │   │   popover.html
│   │   │       │   │   popover.js
│   │   │       │   │   tooltip.html
│   │   │       │   │   tooltip.js
│   │   │       │   │   
│   │   │       │   └───helpers
│   │   │       │           date-parser.js
│   │   │       │           debounce.js
│   │   │       │           dimensions.js
│   │   │       │           parse-options.js
│   │   │       │           raf.js
│   │   │       │           
│   │   │       ├───preloading
│   │   │       │       preloading.css
│   │   │       │       preloading.js
│   │   │       │       
│   │   │       ├───radio-select
│   │   │       │       radio-select.js
│   │   │       │       
│   │   │       ├───rating
│   │   │       │       rating-directive.js
│   │   │       │       rating.css
│   │   │       │       
│   │   │       ├───redactor-directive
│   │   │       │       redactor-directive.js
│   │   │       │       
│   │   │       ├───reportFilters
│   │   │       │       filtersTpl.html
│   │   │       │       reportFilters.js
│   │   │       │       
│   │   │       ├───tags-input
│   │   │       │       ng-tags-input.css
│   │   │       │       ng-tags-input.js
│   │   │       │       
│   │   │       ├───uploader
│   │   │       │       upload.js
│   │   │       │       uploader.js
│   │   │       │       
│   │   │       └───writemaths
│   │   │               rangy-core.js
│   │   │               textinputs_jquery.js
│   │   │               writemaths-directive.js
│   │   │               writemaths.css
│   │   │               writemaths.js
│   │   │               
│   │   ├───filters
│   │   │   │   filters.js
│   │   │   │   
│   │   │   └───_bundle
│   │   │       ├───between
│   │   │       │       between.js
│   │   │       │       
│   │   │       ├───changeBlankSpace
│   │   │       │       changeBlankSpace.js
│   │   │       │       
│   │   │       ├───minimize
│   │   │       │       minimize.js
│   │   │       │       
│   │   │       ├───moment
│   │   │       │       moment.js
│   │   │       │       
│   │   │       ├───tagToString
│   │   │       │       tagToString.js
│   │   │       │       
│   │   │       └───trustedHtml
│   │   │               trustedHtml.js
│   │   │           
│   │   ├───models
│   │   │   ├───AbsenceReason
│   │   │   │       absenceReasonModel.js
│   │   │   │       
│   │   │   ├───adherence
│   │   │   │       adherenceApiModel.js
│   │   │   │       adherenceModel.js
│   │   │   │       
│   │   │   ├───answerSheet
│   │   │   │       answerSheetModel.js
│   │   │   │       
│   │   │   ├───cognitiveCompetence
│   │   │   │       cognitiveCompetenceModel.js
│   │   │   │       
│   │   │   ├───correction
│   │   │   │       correctionApiModel.js
│   │   │   │       correctionModel.js
│   │   │   │       
│   │   │   ├───correlatedSkill
│   │   │   │       correlatedSkillModel.js
│   │   │   │       
│   │   │   ├───course
│   │   │   │       courseModel.js
│   │   │   │       
│   │   │   ├───discipline
│   │   │   │       disciplineModel.js
│   │   │   │       
│   │   │   ├───evaluationMatrix
│   │   │   │       evaluationMatrixModel.js
│   │   │   │       
│   │   │   ├───evaluationMatrixCourse
│   │   │   │       evaluationMatrixCourseModel.js
│   │   │   │       
│   │   │   ├───EvaluationMatrixCourseCurriculumGrade
│   │   │   │       EvaluationMatrixCourseCurriculumGradeModel.js
│   │   │   │       
│   │   │   ├───file
│   │   │   │       fileModel.js
│   │   │   │       
│   │   │   ├───formatType
│   │   │   │       formatTypeModel.js
│   │   │   │       
│   │   │   ├───Integration
│   │   │   │   ├───course
│   │   │   │   │       courseModel.js
│   │   │   │   │       
│   │   │   │   ├───curriculumGrade
│   │   │   │   │       curriculumGradeModel.js
│   │   │   │   │       
│   │   │   │   ├───levelEducation
│   │   │   │   │       levelEducationModel.js
│   │   │   │   │       
│   │   │   │   └───modality
│   │   │   │           modalityModel.js
│   │   │   │           
│   │   │   ├───item
│   │   │   │       itemModel.js
│   │   │   │       
│   │   │   ├───itemLevel
│   │   │   │       itemLevelModel.js
│   │   │   │       
│   │   │   ├───itemSituation
│   │   │   │       itemSituationModel.js
│   │   │   │       
│   │   │   ├───itemType
│   │   │   │       itemTypeModel.js
│   │   │   │       
│   │   │   ├───modelEvaluationMatrix
│   │   │   │       modelEvaluationMatrixModel.js
│   │   │   │       
│   │   │   ├───modelSkillLevel
│   │   │   │       modelSkillLevelModel.js
│   │   │   │       
│   │   │   ├───modelTestModel
│   │   │   │       modelTestModel.js
│   │   │   │       
│   │   │   ├───parameter
│   │   │   │       parameterModel.js
│   │   │   │       
│   │   │   ├───performanceLevel
│   │   │   │       performanceLevelModel.js
│   │   │   │       
│   │   │   ├───reportAnswerSheet
│   │   │   │       reportAnswerSheetModel.js
│   │   │   │       
│   │   │   ├───reportCorrection
│   │   │   │       reportCorrectionModel.js
│   │   │   │       
│   │   │   ├───reportItem
│   │   │   │       reportItemModel.js
│   │   │   │       
│   │   │   ├───reportTest
│   │   │   │       reportTestModel.js
│   │   │   │       
│   │   │   ├───skill
│   │   │   │       skillModel.js
│   │   │   │       
│   │   │   ├───test
│   │   │   │       testAdministrateModel.js
│   │   │   │       testImportExportModel.js
│   │   │   │       testListModel.js
│   │   │   │       testModel.js
│   │   │   │       testRequestRevokeModel.js
│   │   │   │       testRevokeModel.js
│   │   │   │       
│   │   │   ├───TestPerformanceLevel
│   │   │   │       testPerformanceLevelModel.js
│   │   │   │       
│   │   │   ├───testType
│   │   │   │       testTypeModel.js
│   │   │   │       
│   │   │   ├───testTypeCourse
│   │   │   │       testTypeCourseModel.js
│   │   │   │       
│   │   │   ├───testTypeCourseCurriculumGrade
│   │   │   │       testTypeCourseCurriculumGradeModel.js
│   │   │   │       
│   │   │   ├───testTypeItemLevel
│   │   │   │       testTypeItemLevelModel.js
│   │   │   │       
│   │   │   └───typeLevelEducation
│   │   │           typeLevelEducationModel.js
│   │   │           
│   │   └───services
│   │       │   authenticationinterceptor.service.js
│   │       │   services.js
│   │       │   ApiSetting.js
│   │       │   
│   │       └───_bundle
│   │           ├───notification
│   │           │       notification.js
│   │           │       
│   │           ├───pager
│   │           │       services.js
│   │           │       
│   │           ├───util
│   │           │       util.js
│   │                   
│   └───vendor
│       │   bootstrap-3.2.0.js
│       │   jquery-2.1.1.js
│       │   jquery-ui.js
│       │   mathJax.js
│       │   moment.js
│       │   
│       ├───angular-1.4.9
│       │   │   angular-animate.js
│       │   │   angular-aria.js
│       │   │   angular-cookies.js
│       │   │   angular-loader.js
│       │   │   angular-message-format.js
│       │   │   angular-messages.js
│       │   │   angular-mocks.js
│       │   │   angular-resource.js
│       │   │   angular-route.js
│       │   │   angular-sanitize.js
│       │   │   angular-scenario.js
│       │   │   angular-touch.js
│       │   │   angular.js
│       │   │   
│       │   └───i18n
│       ├───compressor
│       │       compressor.js
│       │       
│       ├───datepicker
│       │       datepicker.css
│       │       datepicker.js
│       │       
│       ├───highcharts-4.0.4
│       │   │   highcharts-3d.js
│       │   │   highcharts-all.js
│       │   │   highcharts-more.js
│       │   │   highcharts.js
│       │   │   
│       │   └───modules
│       │           exporting.js
│       │           no-data-to-display.js
│       │           
│       ├───redactor
│       │       accents.gif
│       │       accents_ext.gif
│       │       arrows.gif
│       │       brackets.gif
│       │       clips.js
│       │       fontcolor.js
│       │       fontfamily.js
│       │       fontsize.js
│       │       foreign.gif
│       │       function.png
│       │       greeklower.gif
│       │       greekupper.gif
│       │       imagemanager.js
│       │       mathLatex.css
│       │       mathLatex.js
│       │       matrix.gif
│       │       operators.gif
│       │       redactor-font.eot
│       │       redactor.css
│       │       redactor.js
│       │       redactor.less
│       │       relations.gif
│       │       subsupset.gif
│       │       symbols.gif
│       │       table.js
│       │       
│       └───resumable-js
│               resumable.js
│               test.html
│               
└───tests
    │   conf.js
    │   jasmine-runner.html
    │   karma.conf.js
    │   package.json
    │   
    ├───e2e
    │   └───controllers
    │           OMRController.e2e.js
    │           
    └───unit
        │   razor.js
        │   
        ├───controllers
        │       fileController.test.js
        │       formItemController.test.js
        │       
        ├───directives
        ├───factories
        ├───filters
        ├───models
        └───services

Outras informações