From acba95f8a44d1aeb81276110637a8c28ea2b1cbb Mon Sep 17 00:00:00 2001 From: FinnStutzenstein Date: Fri, 9 Dec 2016 10:44:23 +0100 Subject: [PATCH] changing user import (closes #2666) --- .../templates/motions/motion-import.html | 6 +- .../static/templates/topics/topic-import.html | 2 +- openslides/users/static/js/users/csv.js | 78 ++++++--- openslides/users/static/js/users/site.js | 149 +++++++++++------- .../static/templates/users/user-import.html | 35 ++-- 5 files changed, 169 insertions(+), 101 deletions(-) diff --git a/openslides/motions/static/templates/motions/motion-import.html b/openslides/motions/static/templates/motions/motion-import.html index 6d0de81b3..b12263873 100644 --- a/openslides/motions/static/templates/motions/motion-import.html +++ b/openslides/motions/static/templates/motions/motion-import.html @@ -91,12 +91,12 @@ {{ motion.text | limitTo:80 }}{{ motion.text.length > 80 ? '...' : '' }} {{ motion.reason | limitTo:80 }}{{ motion.reason.length > 80 ? '...' : '' }} - + {{ motion.submitter }} - + {{ motion.category }} @@ -129,7 +129,7 @@ - diff --git a/openslides/topics/static/templates/topics/topic-import.html b/openslides/topics/static/templates/topics/topic-import.html index 2676cd505..4195a0c29 100644 --- a/openslides/topics/static/templates/topics/topic-import.html +++ b/openslides/topics/static/templates/topics/topic-import.html @@ -133,7 +133,7 @@ - diff --git a/openslides/users/static/js/users/csv.js b/openslides/users/static/js/users/csv.js index 75ea503bf..3a2f5c393 100644 --- a/openslides/users/static/js/users/csv.js +++ b/openslides/users/static/js/users/csv.js @@ -5,30 +5,62 @@ angular.module('OpenSlidesApp.users.csv', []) .factory('UserCsvExport', [ - function () { - return function (element, users) { - var csvRows = [ - ['title', 'first_name', 'last_name', 'structure_level', 'number', 'groups', 'comment', 'is_active', 'is_present', 'is_committee'], - ]; - _.forEach(users, function (user) { - var row = []; - row.push('"' + user.title + '"'); - row.push('"' + user.first_name + '"'); - row.push('"' + user.last_name + '"'); - row.push('"' + user.structure_level + '"'); - row.push('"' + user.number + '"'); - row.push('"' + user.groups_id.join(',') + '"'); - row.push('"' + user.comment + '"'); - row.push(user.is_active ? '1' : '0'); - row.push(user.is_present ? '1' : '0'); - row.push(user.is_committee ? '1' : '0'); - csvRows.push(row); - }); + 'Group', + 'gettextCatalog', + function (Group, gettextCatalog) { + return { + export: function (element, users) { + var csvRows = [ + ['title', 'first_name', 'last_name', 'structure_level', 'number', 'groups', 'comment', 'is_active', 'is_present', 'is_committee'], + ]; + _.forEach(users, function (user) { + var row = []; + row.push('"' + user.title + '"'); + row.push('"' + user.first_name + '"'); + row.push('"' + user.last_name + '"'); + row.push('"' + user.structure_level + '"'); + row.push('"' + user.number + '"'); + row.push('"' + user.groups_id.join(',') + '"'); + row.push('"' + user.comment + '"'); + row.push(user.is_active ? '1' : '0'); + row.push(user.is_present ? '1' : '0'); + row.push(user.is_committee ? '1' : '0'); + csvRows.push(row); + }); - var csvString = csvRows.join("%0A"); - element.href = 'data:text/csv;charset=utf-8,' + csvString; - element.download = 'users-export.csv'; - element.target = '_blank'; + var csvString = csvRows.join("%0A"); + element.href = 'data:text/csv;charset=utf-8,' + csvString; + element.download = 'users-export.csv'; + element.target = '_blank'; + }, + + downloadExample: function (element) { + // try to get an example with two groups and one with one group + var groups = Group.getAll(); + var csvGroups = ''; + var csvGroup = ''; + if (groups.length >= 3) { // do not pick groups[0], this is the default group + csvGroups = '"' + gettextCatalog.getString(groups[1].name) + + ', ' + gettextCatalog.getString(groups[2].name) + '"'; + } + if (groups.length >= 2) { + csvGroup = gettextCatalog.getString(groups[groups.length - 1].name); // take last group + } + var csvRows = [ + // column header line + ['title', 'first_name', 'last_name', 'structure_level', 'number', 'groups', 'comment', 'is_active', 'is_present', 'is_committee'], + // example entries + ['Dr.', 'Max', 'Mustermann', 'Berlin','1234567890', csvGroups, 'xyz', '1', '1', ''], + ['', 'John', 'Doe', 'Washington','75/99/8-2', csvGroup, 'abc', '1', '1', ''], + ['', 'Fred', 'Bloggs', 'London', '', '', '', '', '', ''], + ['', '', 'Executive Board', '', '', '', '', '', '', '1'], + + ]; + var csvString = csvRows.join("%0A"); + element.href = 'data:text/csv;charset=utf-8,' + csvString; + element.download = 'users-example.csv'; + element.target = '_blank'; + } }; } ]); diff --git a/openslides/users/static/js/users/site.js b/openslides/users/static/js/users/site.js index 16634da5f..113ed72e9 100644 --- a/openslides/users/static/js/users/site.js +++ b/openslides/users/static/js/users/site.js @@ -682,7 +682,7 @@ angular.module('OpenSlidesApp.users.site', [ // Export as a csv file $scope.csvExport = function () { var element = document.getElementById('downloadLinkCSV'); - UserCsvExport(element, $scope.usersFiltered); + UserCsvExport.export(element, $scope.usersFiltered); }; } ]) @@ -886,7 +886,8 @@ angular.module('OpenSlidesApp.users.site', [ 'gettextCatalog', 'User', 'Group', - function($scope, $q, gettext, gettextCatalog, User, Group) { + 'UserCsvExport', + function($scope, $q, gettext, gettextCatalog, User, Group, UserCsvExport) { // import from textarea $scope.importByLine = function () { $scope.usernames = $scope.userlist[0].split("\n"); @@ -984,24 +985,29 @@ angular.module('OpenSlidesApp.users.site', [ user.number = ""; } // groups + user.groups_id = []; // will be overwritten if there are groups if (user.groups) { - var csvGroups = user.groups.replace(quotionRe, '$1').split(","); - user.groups_id = []; - user.groupnames = []; - if (csvGroups !== '') { - // All group objects are already loaded via the resolve statement from ui-router. - var allGroups = Group.getAll(); - csvGroups.forEach(function(csvGroup) { - allGroups.forEach(function (allGroup) { - if (csvGroup == allGroup.id) { - user.groups_id.push(allGroup.id); - user.groupnames.push(allGroup.name); - } - }); - }); - } - } else { - user.groups_id = []; + user.groups = user.groups.replace(quotionRe, '$1').split(','); + user.groups = _.map(user.groups, function (group) { + return _.trim(group); // remove whitespaces on start or end + }); + + // All group objects are already loaded via the resolve statement from ui-router. + var allGroups = Group.getAll(); + // in allGroupsNames ar all original group names and translated names if a + // translation exists (e.g. for default group Delegates) + var allGroupsNames = []; + _.forEach(allGroups, function (group) { + var groupTranslation = gettextCatalog.getString(group.name); + if (group.name !== groupTranslation) { + allGroupsNames.push(groupTranslation); + } + allGroupsNames.push(group.name); + }); + user.groupsToCreate = _.difference(user.groups, allGroupsNames); + + // for template: + user.groupsNotToCreate = _.difference(user.groups, user.groupsToCreate); } // comment if (user.comment) { @@ -1106,39 +1112,79 @@ angular.module('OpenSlidesApp.users.site', [ // import from csv file $scope.import = function () { $scope.csvImporting = true; - var existingUsers = User.getAll(); - angular.forEach($scope.users, function (user) { - if (!user.importerror) { - // Do nothing on duplicateAction==duplicateActions[0] (keep original) - if (user.duplicate && (user.duplicateAction == $scope.duplicateActions[1])) { - // delete existing user - var deletePromises = []; - existingUsers.forEach(function(user_) { - if (user_.first_name == user.first_name && - user_.last_name == user.last_name && - user_.structure_level == user.structure_level) { - deletePromises.push(User.destroy(user_.id)); - } + + // collect all needed groups and create non existing groups + var groupsToCreate = []; + _.forEach($scope.users, function (user) { + if (!user.importerror && user.groups.length) { + _.forEach(user.groupsToCreate, function (group) { // Just append groups, that are not listed yet. + if (_.indexOf(groupsToCreate, group) == -1) { + groupsToCreate.push(group); + } + }); + } + }); + var createPromises = []; + $scope.groupsCreated = 0; + _.forEach(groupsToCreate, function (groupname) { + var group = { + name: groupname, + permissions: [] + }; + createPromises.push(Group.create(group).then( function (success) { + $scope.groupsCreated++; + })); + }); + + $q.all(createPromises).then(function () { + // reload allGroups, now all new groups are created + var allGroups = Group.getAll(); + var existingUsers = User.getAll(); + + _.forEach($scope.users, function (user) { + if (!user.importerror) { + // Assign all groups + _.forEach(user.groups, function(csvGroup) { + allGroups.forEach(function (allGroup) { + // check with and without translation + if (csvGroup === allGroup.name || + csvGroup === gettextCatalog.getString(allGroup.name)) { + user.groups_id.push(allGroup.id); + } + }); }); - $q.all(deletePromises).then(function() { + + // Do nothing on duplicateAction==duplicateActions[0] (keep original) + if (user.duplicate && (user.duplicateAction == $scope.duplicateActions[1])) { + // delete existing user + var deletePromises = []; + existingUsers.forEach(function(user_) { + if (user_.first_name == user.first_name && + user_.last_name == user.last_name && + user_.structure_level == user.structure_level) { + deletePromises.push(User.destroy(user_.id)); + } + }); + $q.all(deletePromises).then(function() { + User.create(user).then( + function(success) { + user.imported = true; + } + ); + }); + } else if (!user.duplicate || + (user.duplicateAction == $scope.duplicateActions[2])) { + // create user User.create(user).then( function(success) { user.imported = true; } ); - }); - } else if (!user.duplicate || - (user.duplicateAction == $scope.duplicateActions[2])) { - // create user - User.create(user).then( - function(success) { - user.imported = true; - } - ); + } } - } + }); + $scope.csvimported = true; }); - $scope.csvimported = true; }; $scope.clear = function () { $scope.csv.result = null; @@ -1146,20 +1192,7 @@ angular.module('OpenSlidesApp.users.site', [ // download CSV example file $scope.downloadCSVExample = function () { var element = document.getElementById('downloadLink'); - var csvRows = [ - // column header line - ['title', 'first_name', 'last_name', 'structure_level', 'number', 'groups', 'comment', 'is_active', 'is_present', 'is_committee'], - // example entries - ['Dr.', 'Max', 'Mustermann', 'Berlin','1234567890', '"3,4"', 'xyz', '1', '1', ''], - ['', 'John', 'Doe', 'Washington','75/99/8-2', '3', 'abc', '1', '1', ''], - ['', 'Fred', 'Bloggs', 'London', '', '', '', '', '', ''], - ['', '', 'Executive Board', '', '', '5', '', '', '', '1'], - - ]; - var csvString = csvRows.join("%0A"); - element.href = 'data:text/csv;charset=utf-8,' + csvString; - element.download = 'users-example.csv'; - element.target = '_blank'; + UserCsvExport.downloadExample(element); }; } ]) diff --git a/openslides/users/static/templates/users/user-import.html b/openslides/users/static/templates/users/user-import.html index 84a06b640..28c7db2f5 100644 --- a/openslides/users/static/templates/users/user-import.html +++ b/openslides/users/static/templates/users/user-import.html @@ -69,10 +69,6 @@
  • Required comma or semicolon separated values with these column header names in the first row:
    title, first_name, last_name, structure_level, number, groups, comment, is_active, is_present, is_committee -
  • Default groups: - Delegates 2, - Staff 3 - Committees 4
  • At least given name or surname have to be filled in. All other fields are optional and may be empty.
  • Only double quotes are accepted as text delimiter (no single quotes). @@ -102,14 +98,15 @@ {{ duplicates }} duplicates
    - -
    @@ -146,7 +143,11 @@ {{ user.number }} -
    +
    + {{ groupname | translate }} +
    +
    + {{ groupname | translate }}
    @@ -164,16 +165,17 @@ ng-click="user.is_committee = !user.is_committee">
    - -
    -