Repository: syncope Updated Branches: refs/heads/master cb1ac36d8 -> 421c0f8b4
[SYNCOPE-719] aligned derived attibutes to admin console's Project: http://git-wip-us.apache.org/repos/asf/syncope/repo Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/4d2cd5f9 Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/4d2cd5f9 Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/4d2cd5f9 Branch: refs/heads/master Commit: 4d2cd5f9d6324ad81f44d93fd151d1c1853701f7 Parents: cb1ac36 Author: Andrea Patricelli <andrea.patrice...@tirasa.net> Authored: Wed Dec 30 11:26:56 2015 +0100 Committer: Andrea Patricelli <andrea.patrice...@tirasa.net> Committed: Wed Dec 30 11:26:56 2015 +0100 ---------------------------------------------------------------------- .../resources/META-INF/resources/app/index.html | 8 +- .../resources/META-INF/resources/app/js/app.js | 28 ++- .../app/js/controllers/UserController.js | 46 +++-- .../app/js/directives/dynamicAttribute.js | 198 ------------------- .../js/directives/dynamicDerivedAttribute.js | 43 ++++ .../js/directives/dynamicDerivedAttributes.js | 2 +- .../app/js/directives/dynamicPlainAttribute.js | 198 +++++++++++++++++++ .../js/directives/dynamicVirtualAttribute.js | 198 +++++++++++++++++++ .../resources/app/views/dynamicAttribute.html | 58 ------ .../app/views/dynamicDerivedAttribute.html | 5 + .../app/views/dynamicDerivedAttributes.html | 25 +-- .../app/views/dynamicPlainAttribute.html | 58 ++++++ .../app/views/dynamicPlainAttributes.html | 4 +- .../app/views/dynamicVirtualAttribute.html | 58 ++++++ .../META-INF/resources/app/views/editUser.html | 4 +- 15 files changed, 622 insertions(+), 311 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/syncope/blob/4d2cd5f9/client/enduser/src/main/resources/META-INF/resources/app/index.html ---------------------------------------------------------------------- diff --git a/client/enduser/src/main/resources/META-INF/resources/app/index.html b/client/enduser/src/main/resources/META-INF/resources/app/index.html index 117796b..8dd9961 100644 --- a/client/enduser/src/main/resources/META-INF/resources/app/index.html +++ b/client/enduser/src/main/resources/META-INF/resources/app/index.html @@ -69,7 +69,7 @@ under the License. <script src="../webjars/angular-cookies/${angular-cookies.version}/angular-cookies.js"></script> <script src="../webjars/angular-sanitize/${angular-sanitize.version}/angular-sanitize.js"></script> <script src="../webjars/angular-ui-bootstrap/${angular-ui-bootstrap.version}/ui-bootstrap-tpls.js"></script> - <script src="../webjars/angular-ui-select/${angular-ui-select.version}/select.js"></script> + <!--<script src="../webjars/angular-ui-select/${angular-ui-select.version}/select.js"></script>--> <script src="../webjars/angular-growl-2/${angular-growl-2.version}/angular-growl.js"></script> <script type="text/javascript" src="../webjars/bootstrap-select/${bootstrap-select.version}/js/bootstrap-select.min.js"></script> <script src="../webjars/FileSaver.js/${FileSaver.version}/FileSaver.js" type="text/javascript"></script> @@ -89,7 +89,9 @@ under the License. <script src="js/controllers/LanguageController.js"></script> <script src="js/controllers/UserController.js"></script> <!--directives--> - <script src="js/directives/dynamicAttribute.js"></script> + <script src="js/directives/dynamicPlainAttribute.js"></script> + <script src="js/directives/dynamicDerivedAttribute.js"></script> + <script src="js/directives/dynamicVirtualAttribute.js"></script> <script src="js/directives/dynamicPlainAttributes.js"></script> <script src="js/directives/dynamicDerivedAttributes.js"></script> <script src="js/directives/dynamicVirtualAttributes.js"></script> @@ -110,7 +112,7 @@ under the License. <link href="../webjars/ionicons/${ionicons.version}/css/ionicons.min.css" rel="stylesheet" type="text/css" /> <link href="../webjars/angular-ui-select/${angular-ui-select.version}/select.css" rel="stylesheet" type="text/css"/> <link href="../webjars/angular-growl-2/${angular-growl-2.version}/angular-growl.css" rel="stylesheet" type="text/css"/> - <link href="../webjars/select2/${select2.version}/select2.css" rel="stylesheet" /> + <!--<link href="../webjars/select2/${select2.version}/select2.css" rel="stylesheet" />--> <link href="css/app.css" rel="stylesheet" type="text/css" /> <link href="css/login.css" rel="stylesheet" type="text/css" /> <link href="css/editUser.css" rel="stylesheet" type="text/css" /> http://git-wip-us.apache.org/repos/asf/syncope/blob/4d2cd5f9/client/enduser/src/main/resources/META-INF/resources/app/js/app.js ---------------------------------------------------------------------- diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/app.js b/client/enduser/src/main/resources/META-INF/resources/app/js/app.js index 43ea447..4253e11 100644 --- a/client/enduser/src/main/resources/META-INF/resources/app/js/app.js +++ b/client/enduser/src/main/resources/META-INF/resources/app/js/app.js @@ -29,7 +29,7 @@ angular.module('info', []); var app = angular.module('SyncopeEnduserApp', [ 'ui.router', 'ui.bootstrap', - 'ui.select', +// 'ui.select', 'ngSanitize', 'ngAnimate', 'ngResource', @@ -83,15 +83,14 @@ app.config(['$stateProvider', '$urlRouterProvider', '$httpProvider', 'growlProvi url: '/plainSchemas', templateUrl: 'views/user-plain-schemas.html' }) - /*.state('create.derivedSchemas', { - url: '/derivedSchemas', - templateUrl: 'views/user-derived-schemas.html' - }) - .state('create.virtualSchemas', { - url: '/virtualSchemas', - templateUrl: 'views/user-virtual-schemas.html' - })*/ - // url will be /self/create/schema + .state('create.derivedSchemas', { + url: '/derivedSchemas', + templateUrl: 'views/user-derived-schemas.html' + }) + .state('create.virtualSchemas', { + url: '/virtualSchemas', + templateUrl: 'views/user-virtual-schemas.html' + }) .state('create.resources', { url: '/resources', templateUrl: 'views/user-resources.html' @@ -111,7 +110,7 @@ app.config(['$stateProvider', '$urlRouterProvider', '$httpProvider', 'growlProvi }) // nested states // each of these sections will have their own view - // url will be nested (/self/create) + // url will be nested (/self/update) .state('update.credentials', { url: '/credentials', templateUrl: 'views/user-credentials.html', @@ -130,7 +129,7 @@ app.config(['$stateProvider', '$urlRouterProvider', '$httpProvider', 'growlProvi } } }) - /*.state('update.derivedSchemas', { + .state('update.derivedSchemas', { url: '/derivedSchemas', templateUrl: 'views/user-derived-schemas.html', resolve: { @@ -147,8 +146,7 @@ app.config(['$stateProvider', '$urlRouterProvider', '$httpProvider', 'growlProvi return AuthenticationHelper.authenticated(); } } - })*/ - // url will be /self/create/schema + }) .state('update.groups', { url: '/groups', templateUrl: 'views/user-groups.html', @@ -228,7 +226,7 @@ app.config(['$stateProvider', '$urlRouterProvider', '$httpProvider', 'growlProvi } }; }); - + growlProvider.globalTimeToLive(10000); growlProvider.globalPosition('bottom-left'); growlProvider.globalInlineMessages(true); http://git-wip-us.apache.org/repos/asf/syncope/blob/4d2cd5f9/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/UserController.js ---------------------------------------------------------------------- diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/UserController.js b/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/UserController.js index 86ff297..6bf7cb6 100644 --- a/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/UserController.js +++ b/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/UserController.js @@ -45,8 +45,8 @@ angular.module("self").controller("UserController", ['$scope', '$rootScope', '$l plainSchemas: [], derSchemas: [], virSchemas: [], - selectedDerSchemas: [], - selectedVirSchemas: [], +// selectedDerSchemas: [], +// selectedVirSchemas: [], errorMessage: '', attributeTable: {} }; @@ -96,8 +96,14 @@ angular.module("self").controller("UserController", ['$scope', '$rootScope', '$l var derSchemaKey = schemas.derSchemas[i].key; - if ($scope.user.derAttrs[derSchemaKey]) { - $scope.dynamicForm.selectedDerSchemas.push(schemas.derSchemas[i]); + if (!$scope.user.derAttrs[derSchemaKey]) { + + $scope.user.derAttrs[derSchemaKey] = { + schema: derSchemaKey, + values: [], + readonly: true + }; + } } @@ -106,8 +112,31 @@ angular.module("self").controller("UserController", ['$scope', '$rootScope', '$l var virSchemaKey = schemas.virSchemas[i].key; - if ($scope.user.virAttrs[virSchemaKey]) { - $scope.dynamicForm.selectedVirSchemas.push(schemas.virSchemas[i]); + if (!$scope.user.virAttrs[virSchemaKey]) { + + $scope.user.virAttrs[virSchemaKey] = { + schema: virSchemaKey, + values: [], + readonly: schemas.virSchemas[i].readonly + }; + + // initialize multivalue schema and support table: create mode, only first value +// if (schemas.plainSchemas[i].multivalue) { +// $scope.dynamicForm.attributeTable[schemas.plainSchemas[i].key] = { +// fields: [schemas.plainSchemas[i].key + "_" + 0] +// }; +// } + } else { + // initialize multivalue schema and support table: update mode, all provided values +// if (schemas.virSchemas[i].multivalue) { +// $scope.dynamicForm.attributeTable[schemas.virSchemas[i].key] = { +// fields: [schemas.virSchemas[i].key + "_" + 0] +// }; +// // add other values +// for (var j = 1; j < $scope.user.plainAttrs[plainSchemaKey].values.length; j++) { +// $scope.dynamicForm.attributeTable[schemas.plainSchemas[i].key].fields.push(schemas.plainSchemas[i].key + "_" + j); +// } +// } } } @@ -174,15 +203,10 @@ angular.module("self").controller("UserController", ['$scope', '$rootScope', '$l initUserRealm(); } else { - // read user from syncope core readUser(); - // read user security question - } - - initRealms(); //retrieve security available questions initSecurityQuestions(); http://git-wip-us.apache.org/repos/asf/syncope/blob/4d2cd5f9/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicAttribute.js ---------------------------------------------------------------------- diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicAttribute.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicAttribute.js deleted file mode 100644 index 781d251..0000000 --- a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicAttribute.js +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -'use strict'; - -angular.module('self') - .directive('dynamicAttribute', function ($filter) { - return { - restrict: 'E', - templateUrl: 'views/dynamicAttribute.html', - scope: { - schema: "=", - index: "=", - user: "=" - }, - controller: function ($scope, $element, $window) { - $scope.initAttribute = function (schema, index) { - - switch (schema.type) { - case "Long": - case "Double": - $scope.user.plainAttrs[schema.key].values[index] = Number($scope.user.plainAttrs[schema.key].values[index]) - || undefined; - break; - case "Enum": - $scope.enumerationValues = []; - var enumerationValuesSplitted = schema.enumerationValues.toString().split(";"); - for (var i = 0; i < enumerationValuesSplitted.length; i++) { - $scope.enumerationValues.push(enumerationValuesSplitted[i]); - } - $scope.user.plainAttrs[schema.key].values[index] = $scope.user.plainAttrs[schema.key].values[index] - || $scope.enumerationValues[0]; - break; - case "Binary": - - $scope.userFile = $scope.userFile || ''; - //for multivalue fields -// $scope.fileInputId = "fileInputId_" + index; - - $element.bind("change", function (changeEvent) { - $scope.$apply(function () { - var reader = new FileReader(); - var file = changeEvent.target.files[0]; - $scope.userFile = file.name; - reader.onload = function (readerEvt) { - var binaryString = readerEvt.target.result; - $scope.user.plainAttrs[schema.key].values[index] = btoa(binaryString); - }; - reader.readAsBinaryString(file); - }); - }); - - $scope.download = function () { - var byteString = atob($scope.user.plainAttrs[schema.key].values[index]); - - var ab = new ArrayBuffer(byteString.length); - var ia = new Uint8Array(ab); - for (var i = 0; i < byteString.length; i++) { - ia[i] = byteString.charCodeAt(i); - } - - var blob = new Blob([ia], {type: schema.mimeType}); - - saveAs(blob, schema.key); - }; - $scope.remove = function () { - $scope.user.plainAttrs[schema.key].values.splice(index, 1); - $scope.userFile = ''; - $("#fileInput").replaceWith($("#fileInput").clone(true)); - }; - break; - case "Date": - - $scope.selectedDate = $scope.user.plainAttrs[schema.key].values[index]; - $scope.format = $scope.schema.conversionPattern; - $scope.includeTimezone = false; - if ($scope.schema.conversionPattern.indexOf(".SSS") > -1) { - $scope.format = $scope.format.replace(".SSS", ".sss"); - } - if ($scope.schema.conversionPattern.indexOf("Z") > -1) { - $scope.includeTimezone = true; - $scope.format = $scope.format.replace("Z", ""); - } - if ($scope.schema.conversionPattern.indexOf("\'") > -1) { - $scope.format = $scope.format.replace(new RegExp("\'", "g"), ""); - } - - $scope.bindDateToModel = function (selectedDate, format) { - var newFormat = $scope.includeTimezone ? format.concat(" Z") : format; - if (selectedDate) { - selectedDate = $filter('date')(selectedDate, newFormat); - var dateGood = selectedDate.toString(); - $scope.user.plainAttrs[schema.key].values[index] = dateGood; - } else { - $scope.user.plainAttrs[schema.key].values[index] = selectedDate; - } - }; - - $scope.clear = function () { - $scope.user.plainAttrs[schema.key].values[index] = null; - }; - - // Disable weekend selection - $scope.disabled = function (date, mode) { - // example if you want to disable weekends - // return (mode === 'day' && (date.getDay() === 0 || date.getDay() === 6)); - return false; - }; - - $scope.toggleMin = function () { - $scope.minDate = $scope.minDate ? null : new Date(); - }; - - $scope.maxDate = new Date(2050, 5, 22); - - $scope.open = function ($event) { - $scope.status.opened = true; - }; - - $scope.setDate = function (year, month, day) { - $scope.user.plainAttrs[schema.key].values[index] = new Date(year, month, day); - }; - - $scope.dateOptions = { - startingDay: 1 - }; - - $scope.status = { - opened: false - }; - - var tomorrow = new Date(); - tomorrow.setDate(tomorrow.getDate() + 1); - var afterTomorrow = new Date(); - afterTomorrow.setDate(tomorrow.getDate() + 2); - $scope.events = - [ - { - date: tomorrow, - status: 'full' - }, - { - date: afterTomorrow, - status: 'partially' - } - ]; - - $scope.getDayClass = function (date, mode) { - if (mode === 'day') { - var dayToCheck = new Date(date).setHours(0, 0, 0, 0); - - for (var i = 0; i < $scope.events.length; i++) { - var currentDay = new Date($scope.events[i].date).setHours(0, 0, 0, 0); - - if (dayToCheck === currentDay) { - return $scope.events[i].status; - } - } - } - - }; - break; - - case "Boolean": - $scope.user.plainAttrs[schema.key].values[index] = - Boolean($scope.user.plainAttrs[schema.key].values[index]) || false; - break; - - } - }; - - $scope.$watch(function () { - return $scope.user.plainAttrs[$scope.schema.key].values[$scope.index]; - }, function (newValue, oldValue) { - $scope.user.plainAttrs[$scope.schema.key].values = $scope.user.plainAttrs[$scope.schema.key].values - .filter(function (n) { - return (n !== undefined && n !== ""); - }); - }); - }, - replace: true - }; - }); http://git-wip-us.apache.org/repos/asf/syncope/blob/4d2cd5f9/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicDerivedAttribute.js ---------------------------------------------------------------------- diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicDerivedAttribute.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicDerivedAttribute.js new file mode 100644 index 0000000..ff3f4e3 --- /dev/null +++ b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicDerivedAttribute.js @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +'use strict'; + +angular.module('self') + .directive('dynamicDerivedAttribute', function ($filter) { + return { + restrict: 'E', + templateUrl: 'views/dynamicDerivedAttribute.html', + scope: { + schema: "=", + index: "=", + user: "=" + }, + controller: function ($scope, $element, $window) { + $scope.$watch(function () { + return $scope.user.derAttrs[$scope.schema.key].values[$scope.index]; + }, function (newValue, oldValue) { + $scope.user.derAttrs[$scope.schema.key].values = $scope.user.derAttrs[$scope.schema.key].values + .filter(function (n) { + return (n !== undefined && n !== ""); + }); + }); + }, + replace: true + }; + }); http://git-wip-us.apache.org/repos/asf/syncope/blob/4d2cd5f9/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicDerivedAttributes.js ---------------------------------------------------------------------- diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicDerivedAttributes.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicDerivedAttributes.js index 887b5c6..d2a0187 100644 --- a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicDerivedAttributes.js +++ b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicDerivedAttributes.js @@ -44,7 +44,7 @@ angular.module('self') var derSchemaKey = item.key; console.log("REMOVING DERIVED item: ", derSchemaKey); delete $scope.user.derAttrs[derSchemaKey]; - + }; } http://git-wip-us.apache.org/repos/asf/syncope/blob/4d2cd5f9/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicPlainAttribute.js ---------------------------------------------------------------------- diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicPlainAttribute.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicPlainAttribute.js new file mode 100644 index 0000000..18dff97 --- /dev/null +++ b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicPlainAttribute.js @@ -0,0 +1,198 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +'use strict'; + +angular.module('self') + .directive('dynamicPlainAttribute', function ($filter) { + return { + restrict: 'E', + templateUrl: 'views/dynamicPlainAttribute.html', + scope: { + schema: "=", + index: "=", + user: "=" + }, + controller: function ($scope, $element, $window) { + $scope.initAttribute = function (schema, index) { + + switch (schema.type) { + case "Long": + case "Double": + $scope.user.plainAttrs[schema.key].values[index] = Number($scope.user.plainAttrs[schema.key].values[index]) + || undefined; + break; + case "Enum": + $scope.enumerationValues = []; + var enumerationValuesSplitted = schema.enumerationValues.toString().split(";"); + for (var i = 0; i < enumerationValuesSplitted.length; i++) { + $scope.enumerationValues.push(enumerationValuesSplitted[i]); + } + $scope.user.plainAttrs[schema.key].values[index] = $scope.user.plainAttrs[schema.key].values[index] + || $scope.enumerationValues[0]; + break; + case "Binary": + + $scope.userFile = $scope.userFile || ''; + //for multivalue fields +// $scope.fileInputId = "fileInputId_" + index; + + $element.bind("change", function (changeEvent) { + $scope.$apply(function () { + var reader = new FileReader(); + var file = changeEvent.target.files[0]; + $scope.userFile = file.name; + reader.onload = function (readerEvt) { + var binaryString = readerEvt.target.result; + $scope.user.plainAttrs[schema.key].values[index] = btoa(binaryString); + }; + reader.readAsBinaryString(file); + }); + }); + + $scope.download = function () { + var byteString = atob($scope.user.plainAttrs[schema.key].values[index]); + + var ab = new ArrayBuffer(byteString.length); + var ia = new Uint8Array(ab); + for (var i = 0; i < byteString.length; i++) { + ia[i] = byteString.charCodeAt(i); + } + + var blob = new Blob([ia], {type: schema.mimeType}); + + saveAs(blob, schema.key); + }; + $scope.remove = function () { + $scope.user.plainAttrs[schema.key].values.splice(index, 1); + $scope.userFile = ''; + $("#fileInput").replaceWith($("#fileInput").clone(true)); + }; + break; + case "Date": + + $scope.selectedDate = $scope.user.plainAttrs[schema.key].values[index]; + $scope.format = $scope.schema.conversionPattern; + $scope.includeTimezone = false; + if ($scope.schema.conversionPattern.indexOf(".SSS") > -1) { + $scope.format = $scope.format.replace(".SSS", ".sss"); + } + if ($scope.schema.conversionPattern.indexOf("Z") > -1) { + $scope.includeTimezone = true; + $scope.format = $scope.format.replace("Z", ""); + } + if ($scope.schema.conversionPattern.indexOf("\'") > -1) { + $scope.format = $scope.format.replace(new RegExp("\'", "g"), ""); + } + + $scope.bindDateToModel = function (selectedDate, format) { + var newFormat = $scope.includeTimezone ? format.concat(" Z") : format; + if (selectedDate) { + selectedDate = $filter('date')(selectedDate, newFormat); + var dateGood = selectedDate.toString(); + $scope.user.plainAttrs[schema.key].values[index] = dateGood; + } else { + $scope.user.plainAttrs[schema.key].values[index] = selectedDate; + } + }; + + $scope.clear = function () { + $scope.user.plainAttrs[schema.key].values[index] = null; + }; + + // Disable weekend selection + $scope.disabled = function (date, mode) { + // example if you want to disable weekends + // return (mode === 'day' && (date.getDay() === 0 || date.getDay() === 6)); + return false; + }; + + $scope.toggleMin = function () { + $scope.minDate = $scope.minDate ? null : new Date(); + }; + + $scope.maxDate = new Date(2050, 5, 22); + + $scope.open = function ($event) { + $scope.status.opened = true; + }; + + $scope.setDate = function (year, month, day) { + $scope.user.plainAttrs[schema.key].values[index] = new Date(year, month, day); + }; + + $scope.dateOptions = { + startingDay: 1 + }; + + $scope.status = { + opened: false + }; + + var tomorrow = new Date(); + tomorrow.setDate(tomorrow.getDate() + 1); + var afterTomorrow = new Date(); + afterTomorrow.setDate(tomorrow.getDate() + 2); + $scope.events = + [ + { + date: tomorrow, + status: 'full' + }, + { + date: afterTomorrow, + status: 'partially' + } + ]; + + $scope.getDayClass = function (date, mode) { + if (mode === 'day') { + var dayToCheck = new Date(date).setHours(0, 0, 0, 0); + + for (var i = 0; i < $scope.events.length; i++) { + var currentDay = new Date($scope.events[i].date).setHours(0, 0, 0, 0); + + if (dayToCheck === currentDay) { + return $scope.events[i].status; + } + } + } + + }; + break; + + case "Boolean": + $scope.user.plainAttrs[schema.key].values[index] = + Boolean($scope.user.plainAttrs[schema.key].values[index]) || false; + break; + + } + }; + + $scope.$watch(function () { + return $scope.user.plainAttrs[$scope.schema.key].values[$scope.index]; + }, function (newValue, oldValue) { + $scope.user.plainAttrs[$scope.schema.key].values = $scope.user.plainAttrs[$scope.schema.key].values + .filter(function (n) { + return (n !== undefined && n !== ""); + }); + }); + }, + replace: true + }; + }); http://git-wip-us.apache.org/repos/asf/syncope/blob/4d2cd5f9/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicVirtualAttribute.js ---------------------------------------------------------------------- diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicVirtualAttribute.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicVirtualAttribute.js new file mode 100644 index 0000000..5ee0d11 --- /dev/null +++ b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicVirtualAttribute.js @@ -0,0 +1,198 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +'use strict'; + +angular.module('self') + .directive('dynamicAttribute', function ($filter) { + return { + restrict: 'E', + templateUrl: 'views/dynamicPlainAttribute.html', + scope: { + schema: "=", + index: "=", + user: "=" + }, + controller: function ($scope, $element, $window) { + $scope.initAttribute = function (schema, index) { + + switch (schema.type) { + case "Long": + case "Double": + $scope.user.plainAttrs[schema.key].values[index] = Number($scope.user.plainAttrs[schema.key].values[index]) + || undefined; + break; + case "Enum": + $scope.enumerationValues = []; + var enumerationValuesSplitted = schema.enumerationValues.toString().split(";"); + for (var i = 0; i < enumerationValuesSplitted.length; i++) { + $scope.enumerationValues.push(enumerationValuesSplitted[i]); + } + $scope.user.plainAttrs[schema.key].values[index] = $scope.user.plainAttrs[schema.key].values[index] + || $scope.enumerationValues[0]; + break; + case "Binary": + + $scope.userFile = $scope.userFile || ''; + //for multivalue fields +// $scope.fileInputId = "fileInputId_" + index; + + $element.bind("change", function (changeEvent) { + $scope.$apply(function () { + var reader = new FileReader(); + var file = changeEvent.target.files[0]; + $scope.userFile = file.name; + reader.onload = function (readerEvt) { + var binaryString = readerEvt.target.result; + $scope.user.plainAttrs[schema.key].values[index] = btoa(binaryString); + }; + reader.readAsBinaryString(file); + }); + }); + + $scope.download = function () { + var byteString = atob($scope.user.plainAttrs[schema.key].values[index]); + + var ab = new ArrayBuffer(byteString.length); + var ia = new Uint8Array(ab); + for (var i = 0; i < byteString.length; i++) { + ia[i] = byteString.charCodeAt(i); + } + + var blob = new Blob([ia], {type: schema.mimeType}); + + saveAs(blob, schema.key); + }; + $scope.remove = function () { + $scope.user.plainAttrs[schema.key].values.splice(index, 1); + $scope.userFile = ''; + $("#fileInput").replaceWith($("#fileInput").clone(true)); + }; + break; + case "Date": + + $scope.selectedDate = $scope.user.plainAttrs[schema.key].values[index]; + $scope.format = $scope.schema.conversionPattern; + $scope.includeTimezone = false; + if ($scope.schema.conversionPattern.indexOf(".SSS") > -1) { + $scope.format = $scope.format.replace(".SSS", ".sss"); + } + if ($scope.schema.conversionPattern.indexOf("Z") > -1) { + $scope.includeTimezone = true; + $scope.format = $scope.format.replace("Z", ""); + } + if ($scope.schema.conversionPattern.indexOf("\'") > -1) { + $scope.format = $scope.format.replace(new RegExp("\'", "g"), ""); + } + + $scope.bindDateToModel = function (selectedDate, format) { + var newFormat = $scope.includeTimezone ? format.concat(" Z") : format; + if (selectedDate) { + selectedDate = $filter('date')(selectedDate, newFormat); + var dateGood = selectedDate.toString(); + $scope.user.plainAttrs[schema.key].values[index] = dateGood; + } else { + $scope.user.plainAttrs[schema.key].values[index] = selectedDate; + } + }; + + $scope.clear = function () { + $scope.user.plainAttrs[schema.key].values[index] = null; + }; + + // Disable weekend selection + $scope.disabled = function (date, mode) { + // example if you want to disable weekends + // return (mode === 'day' && (date.getDay() === 0 || date.getDay() === 6)); + return false; + }; + + $scope.toggleMin = function () { + $scope.minDate = $scope.minDate ? null : new Date(); + }; + + $scope.maxDate = new Date(2050, 5, 22); + + $scope.open = function ($event) { + $scope.status.opened = true; + }; + + $scope.setDate = function (year, month, day) { + $scope.user.plainAttrs[schema.key].values[index] = new Date(year, month, day); + }; + + $scope.dateOptions = { + startingDay: 1 + }; + + $scope.status = { + opened: false + }; + + var tomorrow = new Date(); + tomorrow.setDate(tomorrow.getDate() + 1); + var afterTomorrow = new Date(); + afterTomorrow.setDate(tomorrow.getDate() + 2); + $scope.events = + [ + { + date: tomorrow, + status: 'full' + }, + { + date: afterTomorrow, + status: 'partially' + } + ]; + + $scope.getDayClass = function (date, mode) { + if (mode === 'day') { + var dayToCheck = new Date(date).setHours(0, 0, 0, 0); + + for (var i = 0; i < $scope.events.length; i++) { + var currentDay = new Date($scope.events[i].date).setHours(0, 0, 0, 0); + + if (dayToCheck === currentDay) { + return $scope.events[i].status; + } + } + } + + }; + break; + + case "Boolean": + $scope.user.plainAttrs[schema.key].values[index] = + Boolean($scope.user.plainAttrs[schema.key].values[index]) || false; + break; + + } + }; + + $scope.$watch(function () { + return $scope.user.plainAttrs[$scope.schema.key].values[$scope.index]; + }, function (newValue, oldValue) { + $scope.user.plainAttrs[$scope.schema.key].values = $scope.user.plainAttrs[$scope.schema.key].values + .filter(function (n) { + return (n !== undefined && n !== ""); + }); + }); + }, + replace: true + }; + }); http://git-wip-us.apache.org/repos/asf/syncope/blob/4d2cd5f9/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicAttribute.html ---------------------------------------------------------------------- diff --git a/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicAttribute.html b/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicAttribute.html deleted file mode 100644 index 9c6b1d9..0000000 --- a/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicAttribute.html +++ /dev/null @@ -1,58 +0,0 @@ -<div ng-switch="schema.type" > - <input ng-switch-when="String" class="form-control" type="text" - ng-model="user.plainAttrs[schema.key].values[index]" - ng-required="schema.mandatoryCondition" - ng-disabled="schema.readonly" ng-init="initAttribute(schema, index)"/> - <input ng-switch-when="Encrypted" class="form-control" type="text" - ng-model="user.plainAttrs[schema.key].values[index]" - ng-required="schema.mandatoryCondition" - ng-disabled="schema.readonly" ng-init="initAttribute(schema, index)"/> - <div ng-switch-when="Boolean"> - <input type="checkbox" ng-model="user.plainAttrs[schema.key].values[index]" ng-required="schema.mandatoryCondition" - ng-init="initAttribute(schema, index)" /> - </div> - <input ng-switch-when="Long" class="form-control" type="number" ng-model="user.plainAttrs[schema.key].values[index]" ng-required="schema.mandatoryCondition" - ng-init="initAttribute(schema, index)" /> - <input ng-switch-when="Double" class="form-control" type="number" ng-model="user.plainAttrs[schema.key].values[index]" ng-required="schema.mandatoryCondition" - ng-init="initAttribute(schema, index)" /> - <p ng-switch-when="Date" class="input-group" > - <input type="text" class="form-control" - uib-datepicker-popup="{{format}}" - ng-model="selectedDate" - ng-change="bindDateToModel(selectedDate, format)" - min-date="minDate" max-date="maxDate" - is-open="status.opened" datepicker-options="dateOptions" - ng-required="schema.mandatoryCondition" close-text="Close" ng-init="initAttribute(schema, index)"/> - <span class="input-group-btn"> - <button type="button" class="btn btn-default" ng-click="open($event)"><i class="glyphicon glyphicon-calendar"></i></button> - </span> - </p> - - <div ng-switch-when="Enum" ng-init="initAttribute(schema, index)"> - <select class="form-control" - ng-model="user.plainAttrs[schema.key].values[index]" - ng-required="schema.mandatoryCondition"> - <option ng-repeat="value in enumerationValues" value="{{value}}">{{schema.enumerationKeys[$index] || value}}</option> - </select> - </div> - - <div ng-switch-when="Binary" ng-init="initAttribute(schema, index)"> - <div enctype="multipart/form-data" accept-charset="UTF-8"> - <input id="fileInput" type="file" ng-required="schema.mandatoryCondition"/> - <button type="button" title="Download file" class="fileButton btn btn-default btn-sm" ng-click="download()"> - <i class="glyphicon glyphicon-download" ></i> - </button> - <button type="button" class="fileButton btn btn-default btn-sm" title="Remove file" ng-click="remove()"> - <i class="glyphicon glyphicon-remove-sign" ></i> - </button> - <h4><span class="label label-primary" ng-model="userFile">{{userFile}}</span></h4> - </div> - - </div> - - <input ng-switch-default class="form-control" type="text" - ng-model="user.plainAttrs[schema.key].values[index]" - ng-required="schema.mandatoryCondition" - ng-disabled="schema.readonly" ng-init="initAttribute(schema, index)"/> - -</div> http://git-wip-us.apache.org/repos/asf/syncope/blob/4d2cd5f9/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicDerivedAttribute.html ---------------------------------------------------------------------- diff --git a/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicDerivedAttribute.html b/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicDerivedAttribute.html new file mode 100644 index 0000000..f0d325b --- /dev/null +++ b/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicDerivedAttribute.html @@ -0,0 +1,5 @@ +<div> + <input class="form-control" type="text" + ng-model="user.derAttrs[schema.key].values[index]" + ng-disabled="true"/> +</div> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/syncope/blob/4d2cd5f9/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicDerivedAttributes.html ---------------------------------------------------------------------- diff --git a/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicDerivedAttributes.html b/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicDerivedAttributes.html index 9400877..5807553 100644 --- a/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicDerivedAttributes.html +++ b/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicDerivedAttributes.html @@ -1,21 +1,4 @@ -<ui-select on-select="addDerivedAttribute($item, $model)" on-remove="removeDerivedAttribute($item, $model)" multiple - ng-model="dynamicForm.selectedDerSchemas" theme="select2" class="attribute-ui-select"> - <ui-select-match placeholder="Select derived attribute...">{{$item.key}}</ui-select-match> - <ui-select-choices repeat="derSchema in dynamicForm.derSchemas | propsFilter: {key: $select.search}"> - <div ng-bind-html="derSchema.key | highlight: $select.search"></div> - <small> - name: {{derSchema.key}} - expression: {{derSchema.expression}} - </small> - </ui-select-choices> -</ui-select> - -<ul class="attribute-virtual-value-container"> - <li class="attribute-virtual-value-field" ng-repeat="selectedDerSchema in dynamicForm.selectedDerSchemas| filter:q as results"> - {{selectedDerSchema.key}} - <input style="font-weight: normal" class="form-control" type="text" ng-disabled="true" ng-model="user.derAttrs[selectedDerSchema.key].values[0]"/> - </li> - <li class="attribute-virtual-value-field" ng-if="results.length == 0"> - <strong>No derived attributes selected...</strong> - </li> -</ul> +<div id="attribute" class="form-group" ng-repeat="derSchema in dynamicForm.derSchemas"> + <label for="derivedSchema.key">{{derSchema.key}} <span ng-if="Boolean(derSchema.mandatoryCondition) === 'true'">*</span></label> + <dynamic-derived-attribute schema="derSchema" user="user" index="0"></dynamic-derived-attribute> +</div> http://git-wip-us.apache.org/repos/asf/syncope/blob/4d2cd5f9/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicPlainAttribute.html ---------------------------------------------------------------------- diff --git a/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicPlainAttribute.html b/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicPlainAttribute.html new file mode 100644 index 0000000..9c6b1d9 --- /dev/null +++ b/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicPlainAttribute.html @@ -0,0 +1,58 @@ +<div ng-switch="schema.type" > + <input ng-switch-when="String" class="form-control" type="text" + ng-model="user.plainAttrs[schema.key].values[index]" + ng-required="schema.mandatoryCondition" + ng-disabled="schema.readonly" ng-init="initAttribute(schema, index)"/> + <input ng-switch-when="Encrypted" class="form-control" type="text" + ng-model="user.plainAttrs[schema.key].values[index]" + ng-required="schema.mandatoryCondition" + ng-disabled="schema.readonly" ng-init="initAttribute(schema, index)"/> + <div ng-switch-when="Boolean"> + <input type="checkbox" ng-model="user.plainAttrs[schema.key].values[index]" ng-required="schema.mandatoryCondition" + ng-init="initAttribute(schema, index)" /> + </div> + <input ng-switch-when="Long" class="form-control" type="number" ng-model="user.plainAttrs[schema.key].values[index]" ng-required="schema.mandatoryCondition" + ng-init="initAttribute(schema, index)" /> + <input ng-switch-when="Double" class="form-control" type="number" ng-model="user.plainAttrs[schema.key].values[index]" ng-required="schema.mandatoryCondition" + ng-init="initAttribute(schema, index)" /> + <p ng-switch-when="Date" class="input-group" > + <input type="text" class="form-control" + uib-datepicker-popup="{{format}}" + ng-model="selectedDate" + ng-change="bindDateToModel(selectedDate, format)" + min-date="minDate" max-date="maxDate" + is-open="status.opened" datepicker-options="dateOptions" + ng-required="schema.mandatoryCondition" close-text="Close" ng-init="initAttribute(schema, index)"/> + <span class="input-group-btn"> + <button type="button" class="btn btn-default" ng-click="open($event)"><i class="glyphicon glyphicon-calendar"></i></button> + </span> + </p> + + <div ng-switch-when="Enum" ng-init="initAttribute(schema, index)"> + <select class="form-control" + ng-model="user.plainAttrs[schema.key].values[index]" + ng-required="schema.mandatoryCondition"> + <option ng-repeat="value in enumerationValues" value="{{value}}">{{schema.enumerationKeys[$index] || value}}</option> + </select> + </div> + + <div ng-switch-when="Binary" ng-init="initAttribute(schema, index)"> + <div enctype="multipart/form-data" accept-charset="UTF-8"> + <input id="fileInput" type="file" ng-required="schema.mandatoryCondition"/> + <button type="button" title="Download file" class="fileButton btn btn-default btn-sm" ng-click="download()"> + <i class="glyphicon glyphicon-download" ></i> + </button> + <button type="button" class="fileButton btn btn-default btn-sm" title="Remove file" ng-click="remove()"> + <i class="glyphicon glyphicon-remove-sign" ></i> + </button> + <h4><span class="label label-primary" ng-model="userFile">{{userFile}}</span></h4> + </div> + + </div> + + <input ng-switch-default class="form-control" type="text" + ng-model="user.plainAttrs[schema.key].values[index]" + ng-required="schema.mandatoryCondition" + ng-disabled="schema.readonly" ng-init="initAttribute(schema, index)"/> + +</div> http://git-wip-us.apache.org/repos/asf/syncope/blob/4d2cd5f9/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicPlainAttributes.html ---------------------------------------------------------------------- diff --git a/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicPlainAttributes.html b/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicPlainAttributes.html index 074abbd..f7759b7 100644 --- a/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicPlainAttributes.html +++ b/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicPlainAttributes.html @@ -1,12 +1,12 @@ <div id="attribute" class="form-group" ng-repeat="plainSchema in dynamicForm.plainSchemas"> <label for="plainSchema.key">{{plainSchema.key}} <span ng-if="Boolean(plainSchema.mandatoryCondition)">*</span></label> <div ng-if="!plainSchema.multivalue"> - <dynamic-attribute schema="plainSchema" user="user" index="0"></dynamic-attribute> + <dynamic-plain-attribute schema="plainSchema" user="user" index="0"></dynamic-plain-attribute> </div> <div ng-if="plainSchema.multivalue"> <div ng-repeat="field in dynamicForm.attributeTable[plainSchema.key].fields track by $index" ng-model='dynamicForm.attributeTable[plainSchema.key].fields[$index]'> - <dynamic-attribute schema="plainSchema" user="user" index="$index"></dynamic-attribute> + <dynamic-plain-attribute schema="plainSchema" user="user" index="$index"></dynamic-plain-attribute> <span> <button class="btn btn-default btn-sm minus" ng-if="$index > 0" type="button" ng-click="removeAttributeField(plainSchema.key, $index)"> <i class="glyphicon glyphicon-minus" title="Remove value"></i> http://git-wip-us.apache.org/repos/asf/syncope/blob/4d2cd5f9/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicVirtualAttribute.html ---------------------------------------------------------------------- diff --git a/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicVirtualAttribute.html b/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicVirtualAttribute.html new file mode 100644 index 0000000..9c6b1d9 --- /dev/null +++ b/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicVirtualAttribute.html @@ -0,0 +1,58 @@ +<div ng-switch="schema.type" > + <input ng-switch-when="String" class="form-control" type="text" + ng-model="user.plainAttrs[schema.key].values[index]" + ng-required="schema.mandatoryCondition" + ng-disabled="schema.readonly" ng-init="initAttribute(schema, index)"/> + <input ng-switch-when="Encrypted" class="form-control" type="text" + ng-model="user.plainAttrs[schema.key].values[index]" + ng-required="schema.mandatoryCondition" + ng-disabled="schema.readonly" ng-init="initAttribute(schema, index)"/> + <div ng-switch-when="Boolean"> + <input type="checkbox" ng-model="user.plainAttrs[schema.key].values[index]" ng-required="schema.mandatoryCondition" + ng-init="initAttribute(schema, index)" /> + </div> + <input ng-switch-when="Long" class="form-control" type="number" ng-model="user.plainAttrs[schema.key].values[index]" ng-required="schema.mandatoryCondition" + ng-init="initAttribute(schema, index)" /> + <input ng-switch-when="Double" class="form-control" type="number" ng-model="user.plainAttrs[schema.key].values[index]" ng-required="schema.mandatoryCondition" + ng-init="initAttribute(schema, index)" /> + <p ng-switch-when="Date" class="input-group" > + <input type="text" class="form-control" + uib-datepicker-popup="{{format}}" + ng-model="selectedDate" + ng-change="bindDateToModel(selectedDate, format)" + min-date="minDate" max-date="maxDate" + is-open="status.opened" datepicker-options="dateOptions" + ng-required="schema.mandatoryCondition" close-text="Close" ng-init="initAttribute(schema, index)"/> + <span class="input-group-btn"> + <button type="button" class="btn btn-default" ng-click="open($event)"><i class="glyphicon glyphicon-calendar"></i></button> + </span> + </p> + + <div ng-switch-when="Enum" ng-init="initAttribute(schema, index)"> + <select class="form-control" + ng-model="user.plainAttrs[schema.key].values[index]" + ng-required="schema.mandatoryCondition"> + <option ng-repeat="value in enumerationValues" value="{{value}}">{{schema.enumerationKeys[$index] || value}}</option> + </select> + </div> + + <div ng-switch-when="Binary" ng-init="initAttribute(schema, index)"> + <div enctype="multipart/form-data" accept-charset="UTF-8"> + <input id="fileInput" type="file" ng-required="schema.mandatoryCondition"/> + <button type="button" title="Download file" class="fileButton btn btn-default btn-sm" ng-click="download()"> + <i class="glyphicon glyphicon-download" ></i> + </button> + <button type="button" class="fileButton btn btn-default btn-sm" title="Remove file" ng-click="remove()"> + <i class="glyphicon glyphicon-remove-sign" ></i> + </button> + <h4><span class="label label-primary" ng-model="userFile">{{userFile}}</span></h4> + </div> + + </div> + + <input ng-switch-default class="form-control" type="text" + ng-model="user.plainAttrs[schema.key].values[index]" + ng-required="schema.mandatoryCondition" + ng-disabled="schema.readonly" ng-init="initAttribute(schema, index)"/> + +</div> http://git-wip-us.apache.org/repos/asf/syncope/blob/4d2cd5f9/client/enduser/src/main/resources/META-INF/resources/app/views/editUser.html ---------------------------------------------------------------------- diff --git a/client/enduser/src/main/resources/META-INF/resources/app/views/editUser.html b/client/enduser/src/main/resources/META-INF/resources/app/views/editUser.html index 3048010..13d50a4 100644 --- a/client/enduser/src/main/resources/META-INF/resources/app/views/editUser.html +++ b/client/enduser/src/main/resources/META-INF/resources/app/views/editUser.html @@ -40,8 +40,8 @@ under the License. <a ui-sref-active="active" ui-sref=".credentials" class="btn btn-default">Credentials</a> <a ui-sref-active="active" ui-sref=".groups" class="btn btn-default">Groups</a> <a ui-sref-active="active" ui-sref=".plainSchemas" class="btn btn-default">Plain Schemas</a> - <!--<a ui-sref-active="active" ui-sref=".derivedSchemas" class="btn btn-default">Derived Schemas</a> - <a ui-sref-active="active" ui-sref=".virtualSchemas" class="btn btn-default">Virtual Schemas</a>--> + <a ui-sref-active="active" ui-sref=".derivedSchemas" class="btn btn-default">Derived Schemas</a> + <a ui-sref-active="active" ui-sref=".virtualSchemas" class="btn btn-default">Virtual Schemas</a> <a ui-sref-active="active" ui-sref=".resources" class="btn btn-default">Resources</a> <a ui-sref-active="active" ui-sref=".finish" class="btn btn-default">Finish</a> </div>