r90 - in trunk: faxtomail-persistence/src/main/xmi faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/content/demande faxtomail-ui-web/src/main/java/com/franciaflex/faxtomail/web/action/admin faxtomail-ui-web/src/main/webapp/WEB-INF/content/admin faxtomail-ui-web/src/main/webapp/css faxtomail-ui-web/src/main/webapp/js
Author: echatellier Date: 2014-05-22 18:02:33 +0200 (Thu, 22 May 2014) New Revision: 90 Url: http://forge.codelutin.com/projects/faxtomail/repository/revisions/90 Log: refs #4662: Sauvegarde de l'ordre des colonnes de l'interface de recherche Added: trunk/faxtomail-ui-web/src/main/webapp/js/select2sortable.js Modified: trunk/faxtomail-persistence/src/main/xmi/faxtomail.zargo trunk/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/content/demande/DemandeListUIHandler.java trunk/faxtomail-ui-web/src/main/java/com/franciaflex/faxtomail/web/action/admin/ConfigurationAction.java trunk/faxtomail-ui-web/src/main/webapp/WEB-INF/content/admin/configuration-input.jsp trunk/faxtomail-ui-web/src/main/webapp/css/configuration.css trunk/faxtomail-ui-web/src/main/webapp/js/configuration.js Modified: trunk/faxtomail-persistence/src/main/xmi/faxtomail.zargo =================================================================== (Binary files differ) Modified: trunk/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/content/demande/DemandeListUIHandler.java =================================================================== --- trunk/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/content/demande/DemandeListUIHandler.java 2014-05-22 13:25:20 UTC (rev 89) +++ trunk/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/content/demande/DemandeListUIHandler.java 2014-05-22 16:02:33 UTC (rev 90) @@ -284,7 +284,7 @@ @Override protected Collection<String> getColumns() { MailFolder selectedFolder = getModel().getSelectedFolder(); - return selectedFolder != null ? selectedFolder.getTableColumns() : null; + return selectedFolder != null ? selectedFolder.getFolderDisplayColumn() : null; } @Override Modified: trunk/faxtomail-ui-web/src/main/java/com/franciaflex/faxtomail/web/action/admin/ConfigurationAction.java =================================================================== --- trunk/faxtomail-ui-web/src/main/java/com/franciaflex/faxtomail/web/action/admin/ConfigurationAction.java 2014-05-22 13:25:20 UTC (rev 89) +++ trunk/faxtomail-ui-web/src/main/java/com/franciaflex/faxtomail/web/action/admin/ConfigurationAction.java 2014-05-22 16:02:33 UTC (rev 90) @@ -34,6 +34,7 @@ import com.franciaflex.faxtomail.persistence.entities.Action; import com.franciaflex.faxtomail.persistence.entities.Configuration; +import com.franciaflex.faxtomail.persistence.entities.ConfigurationImpl; import com.franciaflex.faxtomail.persistence.entities.EtatAttente; import com.franciaflex.faxtomail.persistence.entities.Field; import com.franciaflex.faxtomail.persistence.entities.MailFolder; @@ -116,6 +117,9 @@ } public Configuration getConfiguration() { + if (configuration == null) { + return new ConfigurationImpl(); // just pour eviter les traces struts + } return configuration; } Modified: trunk/faxtomail-ui-web/src/main/webapp/WEB-INF/content/admin/configuration-input.jsp =================================================================== --- trunk/faxtomail-ui-web/src/main/webapp/WEB-INF/content/admin/configuration-input.jsp 2014-05-22 13:25:20 UTC (rev 89) +++ trunk/faxtomail-ui-web/src/main/webapp/WEB-INF/content/admin/configuration-input.jsp 2014-05-22 16:02:33 UTC (rev 90) @@ -35,17 +35,19 @@ <script type="text/javascript" src="<s:url value='/webjars/select2/3.4.8/select2.min.js' />"></script> <script type="text/javascript" src="<s:url value='/webjars/select2/3.4.8/select2_locale_fr.js' />"></script> <script type="text/javascript" src="<s:url value='/webjars/angularjs/1.2.16/angular.min.js' />"></script> + <script type="text/javascript" src="<s:url value='/js/select2sortable.js' />"></script> <script type="text/javascript" src="<s:url value='/nuiton-js-angular-ui-tree/angular-ui-tree.js' />"></script> <script type="text/javascript" src="<s:url value='/js/faxtomail.js' />"></script> <script type="text/javascript" src="<s:url value='/js/configuration.js' />"></script> <script type="text/javascript"> - angular.module('ConfigurationModule', ['FaxToMail', 'ui.tree']) + angular.module('ConfigurationModule', ['FaxToMail', 'ui.tree', 'ui.select2.sortable']) .value('ConfigurationData', { 'etatAttentes' : <s:property value="toJson(etatAttentes)" escapeHtml="false"/>, 'etatAttenteActions': <s:property value="toJson(etatAttenteActions)" escapeHtml="false"/>, 'etatAttenteFields': <s:property value="toJson(etatAttenteFields)" escapeHtml="false"/>, - 'mailFolders': <s:property value="toJson(mailFolders)" escapeHtml="false"/> + 'mailFolders': <s:property value="toJson(mailFolders)" escapeHtml="false"/>, + 'searchDisplayColumns': <s:property value="toJson(configuration.searchDisplayColumns)" escapeHtml="false"/>, }); </script> </head> @@ -76,8 +78,8 @@ <li><a href="#tabs-wait" data-toggle="tab">États d'attente</a></li> <li><a href="#tabs-tree" data-toggle="tab">Arborescence</a></li> <li><a href="#tabs-filters" data-toggle="tab">Filtres de mail</a></li> - <!-- <li><a href="#tabs-rights" data-toggle="tab">Droits</a></li> - <li><a href="#tabs-email-accounts" data-toggle="tab">Comptes mails</a></li> --> + <li><a href="#tabs-search" data-toggle="tab">Recherche</a></li> + <!-- <li><a href="#tabs-email-accounts" data-toggle="tab">Comptes mails</a></li> --> </ul> <div class="tab-content active" ng-controller="ConfigurationMiscController"> @@ -324,9 +326,28 @@ </button> </div> - <!-- <div class="container form-actions"> - <button type="submit" class="btn btn-primary pull-right">Valider</button> - </div> --> + <div id="tabs-search" class="tab-pane" ng-controller="ConfigurationSearchController"> + <input type="hidden" name="configuration.searchDisplayColumns" value="{{searchDisplayColumn.id}}" ng-repeat="searchDisplayColumn in searchDisplayColumns"/> + + <div class="control-group"> + <label class="control-label" for="tableColumns">Champs à afficher dans le tableau (l'ordre peut être changé en faisant un glisser/déposer sur les champs)</label> + + <div class="controls"> + <input type="hidden" ui-select2-sortable ng-model="searchDisplayColumns" simple-query="getObjectsData" multiple sortable> + </div> + + <div> + <table id='table-snapshot' class="table table-bordered"> + <caption>Aperçu</caption> + <thead> + <tr> + <th ng-repeat="etatAttenteField in searchDisplayColumns">{{etatAttenteFields[etatAttenteField.id]}}</th> + </tr> + </thead> + </table> + </div> + </div> + </div> <nav class="navbar navbar-default navbar-fixed-bottom"> <div class="container"> Modified: trunk/faxtomail-ui-web/src/main/webapp/css/configuration.css =================================================================== --- trunk/faxtomail-ui-web/src/main/webapp/css/configuration.css 2014-05-22 13:25:20 UTC (rev 89) +++ trunk/faxtomail-ui-web/src/main/webapp/css/configuration.css 2014-05-22 16:02:33 UTC (rev 90) @@ -41,6 +41,11 @@ padding: 10px 10px; cursor:default; } + +.select2-container { + width: 100%; +} + .angular-ui-tree-handle.bg-warning { background: #fcf8e3; } Modified: trunk/faxtomail-ui-web/src/main/webapp/js/configuration.js =================================================================== --- trunk/faxtomail-ui-web/src/main/webapp/js/configuration.js 2014-05-22 13:25:20 UTC (rev 89) +++ trunk/faxtomail-ui-web/src/main/webapp/js/configuration.js 2014-05-22 16:02:33 UTC (rev 90) @@ -4,8 +4,12 @@ */ FaxToMailModule.controller('ConfigurationController', ['$scope', '$http', 'ConfigurationData', function($scope, $http, ConfigurationData) { - //mail folders + //{Array} mail folders $scope.mailFolders = ConfigurationData.mailFolders; + //{Map} les actions possibles pour les etats d'attentes + $scope.etatAttenteActions = ConfigurationData.etatAttenteActions; + //{Map} les champs obligatoires possibles + $scope.etatAttenteFields = ConfigurationData.etatAttenteFields; }]); /** @@ -23,10 +27,6 @@ function($scope, $http, ConfigurationData) { //{Array} les etats d'attentes disponibles $scope.etatAttentes = ConfigurationData.etatAttentes; - //{Array} les actions possibles pour les etats d'attentes - $scope.etatAttenteActions = ConfigurationData.etatAttenteActions; - //{Array} les champs obligatoires possibles - $scope.etatAttenteFields = ConfigurationData.etatAttenteFields; //{Object} etat d'attente selectionné $scope.selectedEtatAttente; @@ -141,3 +141,35 @@ delete $scope.selectedFolder; }; }]); + + +/** + * Search tab controller. + */ +FaxToMailModule.controller('ConfigurationSearchController', ['$scope', '$http', 'ConfigurationData', + function($scope, $http, ConfigurationData) { + //{Object} Option select2 + $scope.searchSelectOptions = { + 'multiple': true/*, + 'tags': Object.keys($scope.etatAttenteFields)*/ + }; + //{Array} Options actuelle + $scope.searchDisplayColumns = []; + angular.forEach(ConfigurationData.searchDisplayColumns, function(searchDisplayColumn) { + $scope.searchDisplayColumns.push({ + id: searchDisplayColumn, + label: $scope.etatAttenteFields[searchDisplayColumn] + }); + }); + + $scope.getObjectsData = function(term, result) { + var result2 = []; + angular.forEach($scope.etatAttenteFields, function(v, k) { + result2.push({ + id: k, + label: v + }); + }); + result(result2); + }; +}]); Added: trunk/faxtomail-ui-web/src/main/webapp/js/select2sortable.js =================================================================== --- trunk/faxtomail-ui-web/src/main/webapp/js/select2sortable.js (rev 0) +++ trunk/faxtomail-ui-web/src/main/webapp/js/select2sortable.js 2014-05-22 16:02:33 UTC (rev 90) @@ -0,0 +1,254 @@ +/** + * Enhanced Select2 Dropmenus + * + * @AJAX Mode - When in this mode, your value will be an object (or array of objects) of the data used by Select2 + * This change is so that you do not have to do an additional query yourself on top of Select2's own query + * @params [options] {object} The configuration options passed to $.fn.select2(). Refer to the documentation + */ +angular.module('ui.select2.sortable', []).directive('uiSelect2Sortable', ['$timeout', '$filter', function ($timeout, $filter) { + return { + require: 'ngModel', + restrict: 'A', + transclude: true, + scope: { + ngModel: '=', + allowClear: '=?', + simpleQuery: '=?', + simpleData: '=?', + query: '=?', + toId: '=?', + toText: '=?', + sortResults: '=?', + minimumInputLength: '=?', + onSelect: '=?' + }, + link: function (scope, element, attrs, ngModel) { + //create a function to find an id into object + if (!scope.toId) { + scope.toId = function (item) { + if (item._id) { + return item._id; + } + if (item.id) { + return item.id; + } + if (item.uri) { + return item.uri; + } + if (item.href) { + return item.href; + } + if (item.resource) { + return item.resource; + } + return item; + }; + } + + //create a function to find display value into object + if (!scope.toText) { + scope.toText = function (item) { + if (item.text) { + return item.text; + } + if (item.name) { + return item.name; + } + if (item.label) { + return item.label; + } + return item; + }; + } + + //create a function to find display value into object + //this js function is slower than the underscoreJS function below. + //I recommand you to override this function by the underscoreJS one + +// $scope.sortResults = function (results, container, query) { +// return _.sortBy(results, function(item) { +// return item.text; +// }); +// }; + + if (!scope.sortResults) { + scope.sortResults = function (results, container, query) { + // use the built in javascript sort function + return results.sort(function (a, b) { + if (a.text > b.text) { + return 1; + } else if (a.text < b.text) { + return -1; + } else { + return 0; + } + }); + }; + } + + //prepare options for the select2 element + scope.opts = { + multiple: angular.isDefined(attrs.multiple) || false, + sortable: angular.isDefined(attrs.sortable) || false, + minimumInputLength: scope.minimumInputLength || 0, + query: scope.query, + sortResults: scope.sortResults, + allowClear: scope.allowClear || false + }; + + // Convert from Select2 view-model to Angular view-model. + scope.convertToAngularModel = function (select2_data) { + var model; + if (angular.isArray(select2_data)) { + model = []; + angular.forEach(select2_data, function (value) { + model.push(value._data); + }); + } else { + if (select2_data && select2_data._data) { + model = select2_data._data; + } else { + model = select2_data; + } + } + return model; + }; + + // Convert from Angular view-model to Select2 view-model. + scope.convertToSelect2Model = function (angular_data) { + if (angular.isArray(angular_data)) { + var model = []; + angular.forEach( + angular_data, + function (value) { + model.push({ + id: scope.toId(value), + text: scope.toText(value), + _data: value + }); + }); + return model; + } else if (angular.isObject(angular_data)) { + return { + id: scope.toId(angular_data), + text: scope.toText(angular_data), + _data: angular_data + }; + } else if (angular.isString(angular_data)) { + return { + id: angular_data, + text: angular_data, + _data: angular_data + }; + } + + return angular_data; + }; + + //allow user to create a simple query + //just use simpleQuery : function(term, callback) { callback(array_of_dummy_objects; } + if (scope.simpleQuery) { + scope.opts.query = function (query) { + scope.simpleQuery(query.term, function (values) { + query.callback({ results: scope.convertToSelect2Model(values) }); + }); + }; + } else if (scope.simpleData) { + //Use this if you want to filter on the text field without ajax query + //Just use data : [Object object] and the toText function + scope.opts.query = function (query) { + query.callback({ + results: $filter('filter')(scope.convertToSelect2Model(scope.simpleData), {text: query.term}, 'text') + }); + }; + } + + // call select2 function to set data and all properties + scope.render = function () { + if (scope.opts.multiple) { + element.select2('data', scope.convertToSelect2Model(ngModel.$viewValue)); + } else { + if (angular.isObject(ngModel.$viewValue)) { + element.select2('data', scope.convertToSelect2Model(ngModel.$viewValue)); + } else if (!ngModel.$viewValue) { + element.select2('data', null); + } else { + element.select2('data', scope.convertToSelect2Model(ngModel.$viewValue)); + } + } + if (scope.opts.sortable) { + element.select2("container").find("ul.select2-choices").sortable({ + containment: 'parent', + start: function () { + element.select2("onSortStart"); + }, + update: function () { + element.select2("onSortEnd"); + element.trigger('change'); + } + }); + } + }; + + // Set the view and model value and update the angular template manually for the ajax/multiple select2. + element.bind("change", function (event) { + if (scope.$$phase) { + return; + } + var e = event; + scope.$apply(function () { + var values = element.select2('data'); + if (e && e.removed && values) { + for (var i = 0; i < values.length; i++) { + if (values[i] === e.removed) { + values.splice(i, 1); + } + } + } + if (values && (angular.isArray(values) || values._data)) { + values = scope.convertToAngularModel(values); + } + ngModel.$setViewValue(values); + }); + }); + + // Watch the model for programmatic changes + scope.$watch(function () { + return ngModel.$viewValue; + }, function (current, old) { + if (current === old) { + return; + } + scope.render(); + }, true); + + element.bind("$destroy", function () { + element.select2("destroy"); + }); + + //watch disabled attrs to send event to select2 + attrs.$observe('disabled', function (value) { + element.select2('enable', !value); + }); + + // add an onSelect element which retreive model object into e.added or e.removed + if (scope.onSelect) { + element.on("change", function (e) { + if (e.added) { + e.added = scope.convertToAngularModel(e.added); + } + if (e.removed) { + e.removed = scope.convertToAngularModel(e.removed); + } + scope.onSelect(e); + }); + } + + // Initialize the plugin late so that the injected DOM does not disrupt the template compiler + $timeout(function () { + element.select2(scope.opts); + scope.render(); + }); + } + }; +}]); \ No newline at end of file
participants (1)
-
echatellier@users.forge.codelutin.com