mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-01-17 06:52:27 +01:00
[ongoing] import users from csv file: admin inteface
This commit is contained in:
parent
f75633e64e
commit
e7bb41f38d
@ -609,6 +609,32 @@ Application.Controllers.controller('NewMemberController', ['$scope', '$state', '
|
||||
}
|
||||
]);
|
||||
|
||||
/**
|
||||
* Controller used in the member's import page: import from CSV (admin view)
|
||||
*/
|
||||
Application.Controllers.controller('ImportMembersController', ['$scope', '$state', 'Group', 'Training', 'CSRF', 'plans', 'tags',
|
||||
function($scope, $state, Group, Training, CSRF, plans, tags) {
|
||||
CSRF.setMetaTags();
|
||||
|
||||
/* PUBLIC SCOPE */
|
||||
|
||||
// API URL where the form will be posted
|
||||
$scope.actionUrl = '/api/members/import';
|
||||
|
||||
// Form action on the above URL
|
||||
$scope.method = 'post';
|
||||
|
||||
// List of all plans
|
||||
$scope.plans = plans;
|
||||
|
||||
// List of all tags
|
||||
$scope.tags = tags
|
||||
|
||||
// Using the MembersController
|
||||
return new MembersController($scope, $state, Group, Training);
|
||||
}
|
||||
]);
|
||||
|
||||
/**
|
||||
* Controller used in the admin's creation page (admin view)
|
||||
*/
|
||||
|
@ -959,6 +959,20 @@ angular.module('application.router', ['ui.router'])
|
||||
translations: ['Translations', function (Translations) { return Translations.query(['app.admin.members_new', 'app.shared.user', 'app.shared.user_admin']).$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.admin.members_import', {
|
||||
url: '/admin/members/import',
|
||||
views: {
|
||||
'main@': {
|
||||
templateUrl: '<%= asset_path "admin/members/import.html" %>',
|
||||
controller: 'ImportMembersController'
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
translations: ['Translations', function (Translations) { return Translations.query(['app.admin.members_import', 'app.shared.user', 'app.shared.user_admin']).$promise; }],
|
||||
plans: ['Plan', function(Plan) { return Plan.query().$promise }],
|
||||
tags: ['Tag', function(Tag) { return Tag.query().$promise }]
|
||||
}
|
||||
})
|
||||
.state('app.admin.members_edit', {
|
||||
url: '/admin/members/:id/edit',
|
||||
views: {
|
||||
|
@ -180,6 +180,11 @@ p, .widget p {
|
||||
.p-lg { padding: 30px; }
|
||||
.p-l { padding: 16px; }
|
||||
|
||||
.p-h-xs { padding-left: 5px; padding-right: 5px; }
|
||||
.p-h-s { padding-left: 10px; padding-right: 10px; }
|
||||
.p-h-l { padding-left: 16px; padding-right: 16px; }
|
||||
.p-h-lg { padding-left: 30px; padding-right: 30px; }
|
||||
|
||||
.m-xxs{margin: 2px 4px}
|
||||
.m-xs{margin: 5px;}
|
||||
.m-sm{margin: 10px;}
|
||||
@ -256,6 +261,14 @@ p, .widget p {
|
||||
.m-b-n-lg{margin-bottom: -30px}
|
||||
.m-b-n-xl{margin-bottom: -40px}
|
||||
|
||||
.m-h-none{margin-left: 0; margin-right: 0;}
|
||||
.m-h-xs{margin-left: 5px; margin-right: 5px;}
|
||||
.m-h-sm{margin-left: 10px; margin-right: 10px;}
|
||||
.m-h{margin-left: 15px; margin-right: 15px;}
|
||||
.m-h-md{margin-left: 20px; margin-right: 20px;}
|
||||
.m-h-lg{margin-left: 30px; margin-right: 30px;}
|
||||
.m-h-xl{margin-left: 40px; margin-right: 40px;}
|
||||
|
||||
.media-xs{min-width: 50px}
|
||||
.media-sm{min-width: 80px}
|
||||
.media-md{min-width: 90px}
|
||||
|
165
app/assets/templates/admin/members/import.html.erb
Normal file
165
app/assets/templates/admin/members/import.html.erb
Normal file
@ -0,0 +1,165 @@
|
||||
<div>
|
||||
|
||||
<section class="heading b-b">
|
||||
<div class="row no-gutter">
|
||||
|
||||
<div class="col-md-1 hidden-xs">
|
||||
<section class="heading-btn">
|
||||
<a ng-click="cancel()"><i class="fa fa-long-arrow-left"></i></a>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="col-md-8 b-l b-r">
|
||||
<section class="heading-title">
|
||||
<h1 translate>{{ 'members_import.import_members' }}</h1>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="col-md-3">
|
||||
<section class="heading-actions wrapper">
|
||||
<a class="btn btn-lg btn-block btn-default m-t-xs" target="_blank" href="example.csv" translate>
|
||||
{{ 'members_import.download_example' }}
|
||||
</a>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="row p-sm">
|
||||
<div class="col-md-12">
|
||||
<p class="alert alert-info" translate>
|
||||
{{ 'members_import.info' }}
|
||||
</p>
|
||||
<p class="alert alert-warning" translate>
|
||||
{{ 'members_import.required_fields' }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row m-h-sm">
|
||||
|
||||
<div class="col-md-6 p-h-s">
|
||||
<h3 translate>{{ 'members_import.groups' }}</h3>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th translate>{{ 'members_import.group_name' }}</th>
|
||||
<th translate>{{ 'members_import.group_identifier' }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="group in groups">
|
||||
<td>
|
||||
{{ group.name }}
|
||||
</td>
|
||||
<td>
|
||||
{{ group.slug }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 p-h-s">
|
||||
<h3 translate>{{ 'members_import.trainings' }}</h3>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th translate>{{ 'members_import.training_name' }}</th>
|
||||
<th translate>{{ 'members_import.training_identifier' }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="training in trainings | filterDisabled">
|
||||
<td>
|
||||
{{ training.name }}
|
||||
</td>
|
||||
<td>
|
||||
{{ training.id }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row m-h-sm">
|
||||
|
||||
<div class="col-md-6 p-h-s">
|
||||
<h3 translate>{{ 'members_import.plans' }}</h3>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th translate>{{ 'members_import.plan_name' }}</th>
|
||||
<th translate>{{ 'members_import.plan_identifier' }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="plan in plans">
|
||||
<td>
|
||||
{{ plan.name }}
|
||||
</td>
|
||||
<td>
|
||||
{{ plan.slug }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 p-h-s">
|
||||
<h3 translate>{{ 'members_import.tags' }}</h3>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th translate>{{ 'members_import.tag_name' }}</th>
|
||||
<th translate>{{ 'members_import.tag_identifier' }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="tag in tags">
|
||||
<td>
|
||||
{{ tag.name }}
|
||||
</td>
|
||||
<td>
|
||||
{{ tag.id }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row no-gutter">
|
||||
<div class="col-sm-12 col-md-12 b-r nopadding">
|
||||
|
||||
<form role="form" name="importForm" class="form-horizontal" novalidate action="{{ actionUrl }}" ng-upload="submited(content)" upload-options-enable-rails-csrf="true">
|
||||
<section class="panel panel-default bg-light m-lg">
|
||||
|
||||
<div class="panel-body m-r">
|
||||
<div class="row m-t">
|
||||
<div class="col-sm-6 col-sm-offset-5">
|
||||
<div class="form-group">
|
||||
<span>Lorem ipsum dolor sit amet consectetur adipiscing elit</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div> <!-- ./panel-body -->
|
||||
|
||||
|
||||
<div class="panel-footer no-padder">
|
||||
<input type="submit" value="{{ 'save' | translate }}" class="r-b btn-valid btn btn-warning btn-block p-lg btn-lg text-u-c" ng-disabled="importForm.$invalid"/>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
@ -5,11 +5,18 @@
|
||||
<a href="#" ng-click="backPrevLocation($event)"><i class="fa fa-long-arrow-left "></i></a>
|
||||
</section>
|
||||
</div>
|
||||
<div class="col-xs-10 col-sm-10 col-md-8 b-l">
|
||||
<div class="col-xs-8 col-sm-8 col-md-8 b-l">
|
||||
<section class="heading-title">
|
||||
<h1 translate>{{ 'users_management' }}</h1>
|
||||
</section>
|
||||
</div>
|
||||
<div class="col-xs-1 col-xs-offset-1 col-md-offset-2 b-l">
|
||||
<section class="heading-actions wrapper">
|
||||
<a role="button" class="btn btn-default b-2x rounded m-t-sm m-r-sm pull-right" ui-sref="app.admin.members_import">
|
||||
<i class="fa fa-cloud-upload"></i>
|
||||
</a>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
@ -1,13 +1,20 @@
|
||||
json.extract! plan, :id, :base_name, :name, :interval, :interval_count, :group_id, :training_credit_nb, :is_rolling, :description, :type, :ui_weight, :disabled
|
||||
json.amount (plan.amount / 100.00)
|
||||
json.prices plan.prices, partial: 'api/prices/price', as: :price
|
||||
json.plan_file_attributes do
|
||||
json.id plan.plan_file.id
|
||||
json.attachment_identifier plan.plan_file.attachment_identifier
|
||||
end if plan.plan_file
|
||||
# frozen_string_literal: true
|
||||
|
||||
json.partners plan.partners do |partner|
|
||||
json.first_name partner.first_name
|
||||
json.last_name partner.last_name
|
||||
json.email partner.email
|
||||
end if plan.respond_to?(:partners)
|
||||
json.extract! plan, :id, :base_name, :name, :interval, :interval_count, :group_id, :training_credit_nb, :is_rolling, :description, :type,
|
||||
:ui_weight, :disabled
|
||||
json.amount plan.amount / 100.00
|
||||
json.prices plan.prices, partial: 'api/prices/price', as: :price
|
||||
if plan.plan_file
|
||||
json.plan_file_attributes do
|
||||
json.id plan.plan_file.id
|
||||
json.attachment_identifier plan.plan_file.attachment_identifier
|
||||
end
|
||||
end
|
||||
|
||||
if plan.respond_to?(:partners)
|
||||
json.partners plan.partners do |partner|
|
||||
json.first_name partner.first_name
|
||||
json.last_name partner.last_name
|
||||
json.email partner.email
|
||||
end
|
||||
end
|
@ -1,5 +1,8 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
json.array!(@plans) do |plan|
|
||||
json.extract! plan, :id, :base_name, :name, :interval, :interval_count, :group_id, :training_credit_nb, :description, :type, :ui_weight, :disabled
|
||||
json.amount (plan.amount / 100.00)
|
||||
json.extract! plan, :id, :base_name, :name, :interval, :interval_count, :group_id, :training_credit_nb, :description, :type, :ui_weight,
|
||||
:slug, :disabled
|
||||
json.amount plan.amount / 100.00
|
||||
json.plan_file_url plan.plan_file.attachment_url if plan.plan_file
|
||||
end
|
||||
|
@ -569,6 +569,27 @@ en:
|
||||
add_a_member: "Add a member"
|
||||
user_is_an_organization: "User is an organization"
|
||||
|
||||
members_import:
|
||||
# members bulk import
|
||||
members_import:
|
||||
import_members: "Import members"
|
||||
info: "you can upload a CSV file to create new members or update existing ones. Your file must user the identifiers below to specify the group, trainings, suscription and tags of the members."
|
||||
required_fields: "Your file must contain, at least, the following information for each user to create: email, name, first name and group."
|
||||
groups: "Groups"
|
||||
group_name: "Group name"
|
||||
group_identifier: "Identifier to use"
|
||||
trainings: "Trainings"
|
||||
training_name: "Training name"
|
||||
training_identifier: "Identifier to use"
|
||||
plans: "Plans"
|
||||
plan_name: "Plan name"
|
||||
plan_identifier: "Identifier to use"
|
||||
tags: "Tags"
|
||||
tag_name: "Tag name"
|
||||
tag_identifier: "Identifier to use"
|
||||
download_example: "Download the exemple file"
|
||||
select_file: "Choose a file"
|
||||
|
||||
members_edit:
|
||||
# edit a member
|
||||
duration: "Duration:"
|
||||
|
@ -569,6 +569,27 @@ es:
|
||||
add_a_member: "Agregar un miembro"
|
||||
user_is_an_organization: "El usuario es una organización"
|
||||
|
||||
members_import:
|
||||
# members bulk import
|
||||
members_import:
|
||||
import_members: "Import members" # translation_missing
|
||||
info: "you can upload a CSV file to create new members or update existing ones. Your file must user the identifiers below to specify the group, trainings, suscription and tags of the members." # translation_missing
|
||||
required_fields: "Your file must contain, at least, the following information for each user to create: email, name, first name and group." # translation_missing
|
||||
groups: "Groups" # translation_missing
|
||||
group_name: "Group name" # translation_missing
|
||||
group_identifier: "Identifier to use" # translation_missing
|
||||
trainings: "Trainings" # translation_missing
|
||||
training_name: "Training name" # translation_missing
|
||||
training_identifier: "Identifier to use" # translation_missing
|
||||
plans: "Plans" # translation_missing
|
||||
plan_name: "Plan name" # translation_missing
|
||||
plan_identifier: "Identifier to use" # translation_missing
|
||||
tags: "Tags" # translation_missing
|
||||
tag_name: "Tag name" # translation_missing
|
||||
tag_identifier: "Identifier to use" # translation_missing
|
||||
download_example: "Download the exemple file" # translation_missing
|
||||
select_file: "Choose a file" # translation_missing
|
||||
|
||||
members_edit:
|
||||
# edit a member
|
||||
duration: "Duración:"
|
||||
|
@ -569,6 +569,27 @@ fr:
|
||||
add_a_member: "Ajouter un membre"
|
||||
user_is_an_organization: "L'utilisateur est une structure"
|
||||
|
||||
members_import:
|
||||
# import massif de members
|
||||
members_import:
|
||||
import_members: "Importer des membres"
|
||||
info: "Vous pouvez téléverser un fichier CVS afin de créer des nouveaux membres ou de mettre à jour les existants. Votre fichier doit utiliser les identifiants ci-dessous pour spécifier les groupe, formations, abonnement et étiquettes des membres."
|
||||
required_fields: "Votre fichier doit obligatoirement comporter, au minimum, les informations suivantes pour chaque utilisateur à créer : courriel, nom, prénom et groupe."
|
||||
groups: "Groupes"
|
||||
group_name: "Nom du groupe"
|
||||
group_identifier: "Identifiant à utiliser"
|
||||
trainings: "Formations"
|
||||
training_name: "Nom de la formation"
|
||||
training_identifier: "Identifiant à utiliser"
|
||||
plans: "Abonnements"
|
||||
plan_name: "Nom de l'abonnement"
|
||||
plan_identifier: "Identifiant à utiliser"
|
||||
tags: "Étiquettes"
|
||||
tag_name: "Nom de l'étiquette"
|
||||
tag_identifier: "Identifiant à utiliser"
|
||||
download_example: "Télécharger le fichier d'exemple"
|
||||
select_file: "Choisissez un fichier"
|
||||
|
||||
members_edit:
|
||||
# modifier un membre
|
||||
duration: "Durée :"
|
||||
|
@ -569,6 +569,27 @@ pt:
|
||||
add_a_member: "Adicionar membro"
|
||||
user_is_an_organization: "Usuário é uma organização"
|
||||
|
||||
members_import:
|
||||
# members bulk import
|
||||
members_import:
|
||||
import_members: "Import members" # translation_missing
|
||||
info: "you can upload a CSV file to create new members or update existing ones. Your file must user the identifiers below to specify the group, trainings, suscription and tags of the members." # translation_missing
|
||||
required_fields: "Your file must contain, at least, the following information for each user to create: email, name, first name and group." # translation_missing
|
||||
groups: "Groups" # translation_missing
|
||||
group_name: "Group name" # translation_missing
|
||||
group_identifier: "Identifier to use" # translation_missing
|
||||
trainings: "Trainings" # translation_missing
|
||||
training_name: "Training name" # translation_missing
|
||||
training_identifier: "Identifier to use" # translation_missing
|
||||
plans: "Plans" # translation_missing
|
||||
plan_name: "Plan name" # translation_missing
|
||||
plan_identifier: "Identifier to use" # translation_missing
|
||||
tags: "Tags" # translation_missing
|
||||
tag_name: "Tag name" # translation_missing
|
||||
tag_identifier: "Identifier to use" # translation_missing
|
||||
download_example: "Download the exemple file" # translation_missing
|
||||
select_file: "Choose a file" # translation_missing
|
||||
|
||||
members_edit:
|
||||
# edit a member
|
||||
duration: "Duração:"
|
||||
|
3
public/example.csv
Normal file
3
public/example.csv
Normal file
@ -0,0 +1,3 @@
|
||||
id;gender;first_name;last_name;username;email;password;birthdate;address;phone;group;subscription;tags;trainings;website;job;interests;softwares;allow_contact;allow_newsletter;facebook;twitter;googleplus;viadeo;linkedin;instagram;youtube;vimeo;dailymotion;github;echosciences;pinterest;lastfm;flickr
|
||||
;male;jean;dupont;jdupont;jean.dupont@gmail.com;;1970-01-01;12 bvd Libération - 75000 Paris;0123456789;standard;;1,2;1;http://www.example.com;Charpentier;Ping-pong;AutoCAD;yes;no;http://www.facebook.com/jdupont;;;;;;;;;http://github.com/example;;;;
|
||||
43;;;;;;newpassword
|
|
Loading…
x
Reference in New Issue
Block a user