From 31c320f9ef92413342b788415feb28a272412672 Mon Sep 17 00:00:00 2001 From: Emanuel Schuetze Date: Fri, 11 Dec 2015 21:36:09 +0100 Subject: [PATCH] Improved csv import for agenda and users. - Fix users list. --- openslides/agenda/static/js/agenda/site.js | 77 +++++--- .../static/templates/agenda/item-import.html | 168 +++++++++++------ .../locale/angular-gettext/template-en.pot | 178 ++++++++++-------- openslides/users/static/js/users/site.js | 134 ++++++++++--- .../static/templates/users/user-import.html | 157 ++++++++++----- 5 files changed, 475 insertions(+), 239 deletions(-) diff --git a/openslides/agenda/static/js/agenda/site.js b/openslides/agenda/static/js/agenda/site.js index 075c55d1c..14eb466e6 100644 --- a/openslides/agenda/static/js/agenda/site.js +++ b/openslides/agenda/static/js/agenda/site.js @@ -262,14 +262,15 @@ angular.module('OpenSlidesApp.agenda.site', ['OpenSlidesApp.agenda']) .controller('AgendaImportCtrl', [ '$scope', + 'gettext', 'Agenda', 'Customslide', - function($scope, Agenda, Customslide) { + function($scope, gettext, Agenda, Customslide) { // import from textarea $scope.importByLine = function () { - $scope.items = $scope.itemlist[0].split("\n"); + $scope.titleItems = $scope.itemlist[0].split("\n"); $scope.importcounter = 0; - $scope.items.forEach(function(title) { + $scope.titleItems.forEach(function(title) { var item = {title: title}; // TODO: create all items in bulk mode Customslide.create(item).then( @@ -280,29 +281,63 @@ angular.module('OpenSlidesApp.agenda.site', ['OpenSlidesApp.agenda']) }); }; - // import from csv file + // *** CSV import *** + // set initial data for csv import + $scope.items = [] + $scope.separator = ','; + $scope.encoding = 'UTF-8'; + $scope.encodingOptions = ['UTF-8', 'ISO-8859-1']; $scope.csv = { content: null, header: true, - separator: ',', + headerVisible: false, + separator: $scope.separator, + separatorVisible: false, + encoding: $scope.encoding, + encodingVisible: false, result: null }; - $scope.importByCSV = function (result) { - var obj = JSON.parse(JSON.stringify(result)); - $scope.csvimporting = true; - $scope.csvlines = Object.keys(obj).length; - $scope.csvimportcounter = 0; - for (var i = 0; i < obj.length; i++) { - var item = {}; - item.title = obj[i].title; - item.text = obj[i].text; - // TODO: save also 'duration' in related agenda item - Customslide.create(item).then( - function(success) { - $scope.csvimportcounter++; - } - ); - } + // set csv file encoding + $scope.setEncoding = function () { + $scope.csv.encoding = $scope.encoding; + }; + // set csv file encoding + $scope.setSeparator = function () { + $scope.csv.separator = $scope.separator; + }; + // detect if csv file is loaded + $scope.$watch('csv.result', function () { + $scope.items = []; + var quotionRe = /^"(.*)"$/; + angular.forEach($scope.csv.result, function (item) { + // title + if (item.title) { + item.title = item.title.replace(quotionRe, '$1'); + } + if (!item.title) { + item.importerror = true; + item.title_error = gettext('Error: Title is required.'); + } + // text + if (item.text) { + item.text = item.text.replace(quotionRe, '$1'); + } + $scope.items.push(item); + }); + }); + + // import from csv file + $scope.import = function () { + $scope.csvImporting = true; + angular.forEach($scope.items, function (item) { + if (!item.importerror) { + Customslide.create(item).then( + function(success) { + item.imported = true; + } + ); + } + }); $scope.csvimported = true; }; $scope.clear = function () { diff --git a/openslides/agenda/static/templates/agenda/item-import.html b/openslides/agenda/static/templates/agenda/item-import.html index a935e9036..2d08fa05c 100644 --- a/openslides/agenda/static/templates/agenda/item-import.html +++ b/openslides/agenda/static/templates/agenda/item-import.html @@ -11,7 +11,7 @@
-

Import by copy/paste

+

Import by copy/paste

Copy and paste your agenda item titles in this textbox. Keep each item in a single line.

@@ -23,71 +23,121 @@ Keep each item in a single line.

-
- - {{ importcounter }} / {{ items.length }} {{ "imported" | translate }} +
+ + {{ importcounter }} / {{ titleItems.length }} {{ "imported" | translate }}
+
-

Import by CSV file

-

Select a CSV file to import agenda items! - -

Please note:

- - - - -
-

Preview

- - - - - - -
# - Title - Text - Duration
{{ $index+1 }} - {{ item.title }} - {{ item.text }} - {{ item.duration }} -
- -
- -
- - {{ csvimportcounter }} / {{ csvlines }} {{ "imported" | translate }} - +

Import by CSV file

+
+
+

Select a CSV file +

+
+ + +
+ + + +
- - - Back to agenda overview - -
-

-

- +
-
+ +
diff --git a/openslides/locale/angular-gettext/template-en.pot b/openslides/locale/angular-gettext/template-en.pot index 9b6801f3c..f93c06c06 100644 --- a/openslides/locale/angular-gettext/template-en.pot +++ b/openslides/locale/angular-gettext/template-en.pot @@ -4,14 +4,6 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Project-Id-Version: \n" -#: users/static/templates/users/user-import.html:41 -msgid "'title, first_name, last_name, structure level, groups, comment, is active'" -msgstr "" - -#: agenda/static/templates/agenda/item-import.html:41 -msgid "'title, text'" -msgstr "" - #: assignments/static/templates/assignments/assignment-list.html:54 msgid "--- Select phase ---" msgstr "" @@ -20,7 +12,7 @@ msgstr "" msgid "--- Select state ---" msgstr "" -#: users/static/js/users/site.js:323 +#: users/static/js/users/site.js:348 #: users/static/templates/users/user-detail-profile.html:39 #: users/static/templates/users/user-detail.html:37 msgid "About me" @@ -77,7 +69,7 @@ msgstr "" msgid "Agenda item" msgstr "" -#: users/static/templates/users/user-import.html:45 +#: users/static/templates/users/user-import.html:74 msgid "" "At least first name or last name have to be filled in. All\n" " other fields are optional and may be empty." @@ -88,13 +80,11 @@ msgid "Attachment" msgstr "" #: agenda/static/templates/agenda/item-detail.html:6 +#: agenda/static/templates/agenda/item-import.html:139 +#: agenda/static/templates/agenda/item-import.html:36 msgid "Back to agenda" msgstr "" -#: agenda/static/templates/agenda/item-import.html:83 -msgid "Back to agenda overview" -msgstr "" - #: motions/static/templates/motions/motion-import.html:136 msgid "Back to motions overview" msgstr "" @@ -118,7 +108,8 @@ msgstr "" msgid "Back to overview" msgstr "" -#: users/static/templates/users/user-import.html:93 +#: users/static/templates/users/user-import.html:166 +#: users/static/templates/users/user-import.html:36 msgid "Back to users overview" msgstr "" @@ -167,12 +158,9 @@ msgstr "" msgid "Category" msgstr "" -#: agenda/static/templates/agenda/item-import.html:88 -#: users/static/templates/users/user-import.html:98 -msgid "Clear" -msgstr "" - +#: agenda/static/templates/agenda/item-import.html:129 #: motions/static/templates/motions/motion-import.html:126 +#: users/static/templates/users/user-import.html:156 msgid "Clear preview" msgstr "" @@ -185,9 +173,9 @@ msgid "Closed" msgstr "" #: agenda/static/templates/agenda/item-list.html:174 -#: users/static/js/users/site.js:316 +#: users/static/js/users/site.js:341 #: users/static/templates/users/user-detail.html:45 -#: users/static/templates/users/user-import.html:72 +#: users/static/templates/users/user-import.html:94 msgid "Comment" msgstr "" @@ -233,15 +221,15 @@ msgstr "" msgid "Default comment on the ballot paper" msgstr "" -#: users/static/templates/users/user-import.html:42 +#: users/static/templates/users/user-import.html:71 msgid "Default groups" msgstr "" -#: users/static/js/users/site.js:304 +#: users/static/js/users/site.js:329 msgid "Default password" msgstr "" -#: users/static/templates/users/user-import.html:43 +#: users/static/templates/users/user-import.html:72 msgid "Delegate" msgstr "" @@ -287,7 +275,6 @@ msgstr "" msgid "Drag and drop items to change the order of the agenda. Your modification will be saved immediately." msgstr "" -#: agenda/static/templates/agenda/item-import.html:65 #: agenda/static/templates/agenda/item-list.html:114 #: agenda/static/templates/agenda/item-list.html:184 msgid "Duration" @@ -379,7 +366,9 @@ msgstr "" msgid "Elections" msgstr "" +#: agenda/static/templates/agenda/item-import.html:51 #: motions/static/templates/motions/motion-import.html:23 +#: users/static/templates/users/user-import.html:52 msgid "Encoding" msgstr "" @@ -387,6 +376,10 @@ msgstr "" msgid "English" msgstr "" +#: users/static/js/users/site.js:652 +msgid "Error: First or last name is required." +msgstr "" + #: motions/static/js/motions/site.js:618 msgid "Error: Identifier already exists." msgstr "" @@ -395,6 +388,7 @@ msgstr "" msgid "Error: Text is required." msgstr "" +#: agenda/static/js/agenda/site.js:319 #: motions/static/js/motions/site.js:628 msgid "Error: Title is required." msgstr "" @@ -422,9 +416,9 @@ msgstr "" msgid "Filter" msgstr "" -#: users/static/js/users/site.js:270 +#: users/static/js/users/site.js:295 #: users/static/templates/users/user-detail-profile.html:26 -#: users/static/templates/users/user-import.html:68 +#: users/static/templates/users/user-import.html:90 msgid "First name" msgstr "" @@ -440,10 +434,10 @@ msgstr "" msgid "Group" msgstr "" -#: users/static/js/users/site.js:291 +#: users/static/js/users/site.js:316 #: users/static/templates/users/group-list.html:13 #: users/static/templates/users/user-detail.html:33 -#: users/static/templates/users/user-import.html:71 +#: users/static/templates/users/user-import.html:93 #: users/static/templates/users/user-list.html:10 #: users/static/templates/users/user-list.html:109 msgid "Groups" @@ -482,11 +476,9 @@ msgid "Identifier, reason, submitter and category are optional and may be empty. msgstr "" #: agenda/static/templates/agenda/item-import.html:25 -#: agenda/static/templates/agenda/item-import.html:75 #: agenda/static/templates/agenda/item-list.html:14 #: motions/static/templates/motions/motion-list.html:18 #: users/static/templates/users/user-import.html:25 -#: users/static/templates/users/user-import.html:85 #: users/static/templates/users/user-list.html:14 msgid "Import" msgstr "" @@ -495,8 +487,8 @@ msgstr "" msgid "Import agenda items" msgstr "" -#: agenda/static/templates/agenda/item-import.html:35 -#: users/static/templates/users/user-import.html:35 +#: agenda/static/templates/agenda/item-import.html:42 +#: users/static/templates/users/user-import.html:42 msgid "Import by CSV file" msgstr "" @@ -513,15 +505,23 @@ msgstr "" msgid "Import participants" msgstr "" +#: agenda/static/templates/agenda/item-import.html:132 +msgid "Import {{ items.length - itemsFailed.length }} items" +msgstr "" + #: motions/static/templates/motions/motion-import.html:129 msgid "Import {{ motions.length - motionsFailed.length }} motions" msgstr "" -#: users/static/js/users/site.js:722 +#: users/static/templates/users/user-import.html:159 +msgid "Import {{ users.length - usersFailed.length }} participants" +msgstr "" + +#: users/static/js/users/site.js:809 msgid "Important: Please change your password!" msgstr "" -#: users/static/js/users/site.js:720 +#: users/static/js/users/site.js:807 msgid "Installation was successfully." msgstr "" @@ -531,11 +531,12 @@ msgstr "" msgid "Invalid votes" msgstr "" -#: users/static/js/users/site.js:338 +#: users/static/js/users/site.js:363 +#: users/static/templates/users/user-import.html:95 msgid "Is active" msgstr "" -#: users/static/js/users/site.js:331 +#: users/static/js/users/site.js:356 #: users/static/templates/users/user-list.html:70 msgid "Is present" msgstr "" @@ -544,9 +545,9 @@ msgstr "" msgid "Item number" msgstr "" -#: users/static/js/users/site.js:277 +#: users/static/js/users/site.js:302 #: users/static/templates/users/user-detail-profile.html:30 -#: users/static/templates/users/user-import.html:69 +#: users/static/templates/users/user-import.html:91 msgid "Last name" msgstr "" @@ -692,7 +693,9 @@ msgstr "" msgid "Old speakers:" msgstr "" +#: agenda/static/templates/agenda/item-import.html:71 #: motions/static/templates/motions/motion-import.html:43 +#: users/static/templates/users/user-import.html:76 msgid "Only double quotes are accepted as text delimiter (no single quotes)." msgstr "" @@ -743,9 +746,9 @@ msgstr "" msgid "Phase" msgstr "" -#: agenda/static/templates/agenda/item-import.html:38 +#: agenda/static/templates/agenda/item-import.html:66 #: motions/static/templates/motions/motion-import.html:38 -#: users/static/templates/users/user-import.html:38 +#: users/static/templates/users/user-import.html:67 msgid "Please note:" msgstr "" @@ -766,9 +769,9 @@ msgstr "" msgid "Present" msgstr "" -#: agenda/static/templates/agenda/item-import.html:58 +#: agenda/static/templates/agenda/item-import.html:78 #: motions/static/templates/motions/motion-import.html:50 -#: users/static/templates/users/user-import.html:62 +#: users/static/templates/users/user-import.html:83 msgid "Preview" msgstr "" @@ -838,20 +841,12 @@ msgstr "" msgid "Remove message" msgstr "" -#: agenda/static/templates/agenda/item-import.html:44 -#: users/static/templates/users/user-import.html:48 -msgid "Required CSV file encoding is UTF-8." -msgstr "" - +#: agenda/static/templates/agenda/item-import.html:68 #: motions/static/templates/motions/motion-import.html:40 +#: users/static/templates/users/user-import.html:69 msgid "Required comma or semicolon separated values with these column header names in the first row" msgstr "" -#: agenda/static/templates/agenda/item-import.html:40 -#: users/static/templates/users/user-import.html:40 -msgid "Required comma separated values" -msgstr "" - #: core/static/templates/core/projector-controls.html:99 msgid "Reset countdown" msgstr "" @@ -899,23 +894,17 @@ msgstr "" msgid "Select" msgstr "" +#: agenda/static/templates/agenda/item-import.html:45 #: motions/static/templates/motions/motion-import.html:17 +#: users/static/templates/users/user-import.html:46 msgid "Select a CSV file" msgstr "" -#: agenda/static/templates/agenda/item-import.html:36 -msgid "Select a CSV file to import agenda items!" -msgstr "" - -#: users/static/templates/users/user-import.html:36 -msgid "Select a CSV file to import users!" -msgstr "" - #: motions/static/js/motions/site.js:214 msgid "Select or search a category..." msgstr "" -#: users/static/js/users/site.js:297 +#: users/static/js/users/site.js:322 msgid "Select or search a group..." msgstr "" @@ -947,7 +936,9 @@ msgstr "" msgid "Select or search an attachment..." msgstr "" +#: agenda/static/templates/agenda/item-import.html:48 #: motions/static/templates/motions/motion-import.html:20 +#: users/static/templates/users/user-import.html:49 msgid "Separator" msgstr "" @@ -980,7 +971,7 @@ msgstr "" msgid "Special values" msgstr "" -#: users/static/templates/users/user-import.html:44 +#: users/static/templates/users/user-import.html:73 msgid "Staff" msgstr "" @@ -1005,10 +996,10 @@ msgstr "" msgid "Stop current speaker" msgstr "" -#: users/static/js/users/site.js:284 +#: users/static/js/users/site.js:309 #: users/static/templates/users/user-detail-profile.html:35 #: users/static/templates/users/user-detail.html:31 -#: users/static/templates/users/user-import.html:70 +#: users/static/templates/users/user-import.html:92 #: users/static/templates/users/user-list.html:104 msgid "Structure level" msgstr "" @@ -1052,7 +1043,7 @@ msgstr "" msgid "Tags" msgstr "" -#: agenda/static/templates/agenda/item-import.html:64 +#: agenda/static/templates/agenda/item-import.html:85 #: core/static/js/core/site.js:472 #: motions/static/js/motions/site.js:169 #: motions/static/templates/motions/motion-detail.html:232 @@ -1060,17 +1051,12 @@ msgstr "" msgid "Text" msgstr "" -#: agenda/static/templates/agenda/item-import.html:42 -msgid "Text and duration are optional and may be empty." -msgstr "" - -#: agenda/static/templates/agenda/item-import.html:43 -#: users/static/templates/users/user-import.html:47 -msgid "The header in first line is required." +#: agenda/static/templates/agenda/item-import.html:70 +msgid "Text is optional and may be empty." msgstr "" #. academic degree -#: agenda/static/templates/agenda/item-import.html:63 +#: agenda/static/templates/agenda/item-import.html:84 #: agenda/static/templates/agenda/item-list.html:170 #: assignments/static/js/assignments/site.js:77 #: assignments/static/templates/assignments/assignment-list.html:140 @@ -1081,9 +1067,9 @@ msgstr "" #: motions/static/js/motions/site.js:161 #: motions/static/templates/motions/motion-import.html:57 #: motions/static/templates/motions/motion-list.html:95 -#: users/static/js/users/site.js:263 +#: users/static/js/users/site.js:288 #: users/static/templates/users/user-detail-profile.html:22 -#: users/static/templates/users/user-import.html:67 +#: users/static/templates/users/user-import.html:89 msgid "Title" msgstr "" @@ -1109,13 +1095,13 @@ msgstr "" msgid "Uploaded by" msgstr "" -#: users/static/js/users/site.js:721 +#: users/static/js/users/site.js:808 msgid "Use admin and admin for first login." msgstr "" -#: agenda/static/templates/agenda/item-import.html:45 +#: agenda/static/templates/agenda/item-import.html:72 #: motions/static/templates/motions/motion-import.html:44 -#: users/static/templates/users/user-import.html:49 +#: users/static/templates/users/user-import.html:77 msgid "Use the CSV example file from OpenSlides Wiki." msgstr "" @@ -1125,7 +1111,7 @@ msgstr "" msgid "Username" msgstr "" -#: users/static/js/users/site.js:742 +#: users/static/js/users/site.js:829 msgid "Username or password was not correct." msgstr "" @@ -1171,6 +1157,10 @@ msgstr "" msgid "Yes" msgstr "" +#: agenda/static/templates/agenda/item-import.html:112 +msgid "agenda items will be not imported." +msgstr "" + #: assignments/static/templates/assignments/assignment-list.html:72 msgid "elections" msgstr "" @@ -1181,9 +1171,7 @@ msgid "h" msgstr "" #: agenda/static/templates/agenda/item-import.html:28 -#: agenda/static/templates/agenda/item-import.html:78 #: users/static/templates/users/user-import.html:28 -#: users/static/templates/users/user-import.html:88 msgid "imported" msgstr "" @@ -1191,6 +1179,14 @@ msgstr "" msgid "items" msgstr "" +#: agenda/static/templates/agenda/item-import.html:125 +msgid "items were successfully imported." +msgstr "" + +#: agenda/static/templates/agenda/item-import.html:118 +msgid "items will be imported." +msgstr "" + #: motions/static/templates/motions/motion-detail.html:117 msgid "majority" msgstr "" @@ -1215,6 +1211,18 @@ msgstr "" msgid "participants" msgstr "" +#: users/static/templates/users/user-import.html:152 +msgid "participants were successfully imported." +msgstr "" + +#: users/static/templates/users/user-import.html:145 +msgid "participants will be imported." +msgstr "" + +#: users/static/templates/users/user-import.html:139 +msgid "participants will be not imported." +msgstr "" + #: agenda/static/templates/agenda/item-list.html:99 #: assignments/static/templates/assignments/assignment-list.html:73 #: motions/static/templates/motions/motion-list.html:79 @@ -1225,3 +1233,7 @@ msgstr "" #: motions/static/templates/motions/motion-detail.html:118 msgid "undocumented" msgstr "" + +#: users/static/templates/users/user-import.html:127 +msgid "{{ groupname }}" +msgstr "" diff --git a/openslides/users/static/js/users/site.js b/openslides/users/static/js/users/site.js index 01d41d968..314ce6653 100644 --- a/openslides/users/static/js/users/site.js +++ b/openslides/users/static/js/users/site.js @@ -80,6 +80,11 @@ angular.module('OpenSlidesApp.users.site', ['OpenSlidesApp.users']) .state('users.user.import', { url: '/import', controller: 'UserImportCtrl', + resolve: { + groups: function(Group) { + return Group.findAll(); + } + } }) // groups .state('users.group', { @@ -372,6 +377,7 @@ angular.module('OpenSlidesApp.users.site', ['OpenSlidesApp.users']) function($scope, $state, ngDialog, User, Group) { User.bindAll({}, $scope, 'users'); Group.bindAll({}, $scope, 'groups'); + $scope.alert = {}; // setup table sorting $scope.sortColumn = 'first_name'; //TODO: sort by first OR last name @@ -408,7 +414,7 @@ angular.module('OpenSlidesApp.users.site', ['OpenSlidesApp.users']) }; // save changed user $scope.save = function (user) { - Assignment.save(user).then( + User.save(user).then( function(success) { //user.quickEdit = false; $scope.alert.show = false; @@ -572,13 +578,15 @@ angular.module('OpenSlidesApp.users.site', ['OpenSlidesApp.users']) .controller('UserImportCtrl', [ '$scope', + 'gettext', 'User', - function($scope, User) { + 'Group', + function($scope, gettext, User, Group) { // import from textarea $scope.importByLine = function () { - $scope.users = $scope.userlist[0].split("\n"); + $scope.usernames = $scope.userlist[0].split("\n"); $scope.importcounter = 0; - $scope.users.forEach(function(name) { + $scope.usernames.forEach(function(name) { // Split each full name in first and last name. // The last word is set as last name, rest is the first name(s). // (e.g.: "Max Martin Mustermann" -> last_name = "Mustermann") @@ -598,42 +606,106 @@ angular.module('OpenSlidesApp.users.site', ['OpenSlidesApp.users']) }); }; - // import from csv file + // *** csv import *** + // set initial data for csv import + $scope.users = [] + $scope.separator = ','; + $scope.encoding = 'UTF-8'; + $scope.encodingOptions = ['UTF-8', 'ISO-8859-1']; $scope.csv = { content: null, header: true, - separator: ',', + headerVisible: false, + separator: $scope.separator, + separatorVisible: false, + encoding: $scope.encoding, + encodingVisible: false, result: null }; - - $scope.importByCSV = function (result) { - var obj = JSON.parse(JSON.stringify(result)); - $scope.csvimporting = true; - $scope.csvlines = Object.keys(obj).length; - $scope.csvimportcounter = 0; - for (var i = 0; i < obj.length; i++) { - var user = {}; - user.title = obj[i].titel; - user.first_name = obj[i].first_name; - user.last_name = obj[i].last_name; - user.structure_level = obj[i].structure_level; - user.groups = []; - if (obj[i].groups !== '') { - var groups = obj[i].groups.replace('"','').split(","); - groups.forEach(function(group) { - user.groups.push(group); - }); + // set csv file encoding + $scope.setEncoding = function () { + $scope.csv.encoding = $scope.encoding; + }; + // set csv file encoding + $scope.setSeparator = function () { + $scope.csv.separator = $scope.separator; + }; + // detect if csv file is loaded + $scope.$watch('csv.result', function () { + $scope.users = []; + var quotionRe = /^"(.*)"$/; + angular.forEach($scope.csv.result, function (user) { + // title + if (user.title) { + user.title = user.title.replace(quotionRe, '$1'); } - user.comment = obj[i].comment; - User.create(user).then( - function(success) { - $scope.csvimportcounter++; + // first name + if (user.first_name) { + user.first_name = user.first_name.replace(quotionRe, '$1'); + } + // last name + if (user.last_name) { + user.last_name = user.last_name.replace(quotionRe, '$1'); + } + if (!user.first_name && !user.last_name) { + user.importerror = true; + user.name_error = gettext('Error: First or last name is required.'); + } + // structure level + if (user.structure_level) { + user.structure_level = user.structure_level.replace(quotionRe, '$1'); + } + // groups + if (user.groups) { + var csvGroups = user.groups.replace(quotionRe, '$1').split(","); + user.groups = []; + 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.push(allGroup.id); + user.groupnames.push(allGroup.name); + } + }); + }); } - ); - } + } else { + user.groups = []; + } + // comment + if (user.comment) { + user.comment = user.comment.replace(quotionRe, '$1'); + } + // is active + if (user.is_active) { + user.is_active = user.is_active.replace(quotionRe, '$1'); + if (user.is_active == '1') { + user.is_active = true; + } else { + user.is_active = false; + } + } + $scope.users.push(user); + }); + }); + + // import from csv file + $scope.import = function () { + $scope.csvImporting = true; + angular.forEach($scope.users, function (user) { + if (!user.importerror) { + User.create(user).then( + function(success) { + user.imported = true; + } + ); + } + }); $scope.csvimported = true; }; - $scope.clear = function () { $scope.csv.result = null; }; diff --git a/openslides/users/static/templates/users/user-import.html b/openslides/users/static/templates/users/user-import.html index d2e6d98b8..575eaad0b 100644 --- a/openslides/users/static/templates/users/user-import.html +++ b/openslides/users/static/templates/users/user-import.html @@ -11,7 +11,7 @@
-

Import by copy/paste

+

Import by copy/paste

Copy and paste your participant names in this textbox. Keep each person in a single line.

@@ -23,81 +23,148 @@
-
- - {{ importcounter }} / {{ users.length }} {{ "imported" | translate }} +
+ + {{ importcounter }} / {{ usernames.length }} {{ "imported" | translate }}
+
-

Import by CSV file

-

Select a CSV file to import users! +

Import by CSV file

-

Please note:

+
+
+

Select a CSV file +

+
+ + +
+ + + +
+
+ +

Please note:

    -
  • Required comma separated values:
    - 'title, first_name, last_name, structure level, groups, comment, is active' +
  • Required comma or semicolon separated values with these column header names in the first row:
    + 'title, first_name, last_name, structure level, groups, comment, is active'
  • Default groups: Delegate 3, Staff 4
  • At least first name or last name have to be filled in. All other fields are optional and may be empty. -
  • The header in first line is required. -
  • Required CSV file encoding is UTF-8. +
  • Only double quotes are accepted as text delimiter (no single quotes).
  • Use the CSV example file from OpenSlides Wiki.
- - -
+

Preview

+ - + + -
# Title First name Last name Structure level Groups - Comment
Comment + Is active
{{ $index+1 }} - {{ user.title }} - {{ user.first_name }} - {{ user.last_name }} - {{ user.structure_level }} - {{ user.groups }} - {{ user.comment }} + + + + + + + + + + + + {{ $index + 1 }} + + {{ user.title }} + + + + + {{ user.first_name }} + + + + + {{ user.last_name }} + + {{ user.structure_level }} + +
+ {{ groupname }} +
+
+ {{ user.comment }} + +
-
- -
- - {{ csvimportcounter }} / {{ csvlines }} {{ "imported" | translate }} - +
+
+ + {{ usersFailed.length }} + participants will be not imported. +
+
+
+ + {{ users.length - usersFailed.length }} + participants will be imported. +
+
+
+
+ + {{ usersImported.length }} + participants were successfully imported. +
+ +
+ + +
+ - - - Back to users overview - -
-

-

- -