This commit is contained in:
ariasia
2017-03-30 13:20:10 +00:00
62 changed files with 2030 additions and 231 deletions

View File

@ -46,6 +46,8 @@
<script src="bower_components/angular-material/angular-material.js"></script>
<script src="bower_components/angular-ui-router/release/angular-ui-router.js"></script>
<script src="bower_components/angular-material-icons/angular-material-icons.min.js"></script>
<script src="bower_components/underscore/underscore.js"></script>
<script src="bower_components/angular-file-upload/dist/angular-file-upload.min.js"></script>
<!-- endbower -->
<!-- endbuild -->
@ -54,6 +56,10 @@
<script src="scripts/controllers/login.js"></script>
<script src="scripts/controllers/studentSpace.js"></script>
<script src="scripts/controllers/responsableFormationSpace.js"></script>
<script src="scripts/controllers/administrationSpace.js"></script>
<script src="scripts/controllers/administrationDialog.js"></script>
<script src="scripts/services/Filters.js"></script>
<!-- endbuild -->
</body>
</html>

View File

@ -14,7 +14,8 @@ var app = angular.module('clientApp', [
'ngSanitize',
'ngMaterial',
'ui.router',
'ngMdIcons'
'ngMdIcons',
'angularFileUpload'
]);
app.config(function ($stateProvider, $urlRouterProvider) {
@ -37,10 +38,16 @@ app.config(function ($stateProvider, $urlRouterProvider) {
templateUrl: 'views/studentSpace.html',
controller: 'StudentSpaceCtrl'
})
.state('responsableFormationSpace', {
url: '/espace-formation',
templateUrl: 'views/responsableFormationSpace.html',
controller: 'ResponsableFormationSpaceCtrl'
})
.state('administrationSpace', {
url: '/espace-secretariat',
templateUrl: 'views/administrationSpace.html',
controller: 'AdministrationSpaceCtrl'
});
});

View File

@ -0,0 +1,104 @@
(function () {
'use strict';
/**
* @ngdoc function
* @name frontendApp.controller:AdministrationDialogCtrl
* @description
* # AdministrationDialogCtrl
* Controller of the frontendApp
*/
angular.module('clientApp')
.controller('AdministrationDialogCtrl', function ($scope, $state, FileUploader, $mdDialog, fileNameFilter, illegalFileNamesFilter, type) {
console.log(type);
// Public methods -------------------
$scope.hide = function () {
$mdDialog.hide();
};
$scope.cancel = function () {
$mdDialog.cancel();
};
$scope.answer = function (answer) {
$mdDialog.hide(answer);
};
$scope.allDocumentsAreIllegal = function() {
return (fileNameFilter(uploader.queue, type).length === 0);
};
$scope.areThereIllegalFiles = function() {
return (illegalFileNamesFilter(uploader.queue, type).length !== 0);
};
var uploader = $scope.uploader = new FileUploader({
url: 'upload.php'
});
// Private methods ------------------
// FILTERS
// a sync filter
uploader.filters.push({
name: 'syncFilter',
fn: function (item /*{File|FileLikeObject}*/, options) {
console.log('syncFilter');
return this.queue.length < 10;
}
});
// an async filter
uploader.filters.push({
name: 'asyncFilter',
fn: function (item /*{File|FileLikeObject}*/, options, deferred) {
console.log('asyncFilter');
setTimeout(deferred.resolve, 1e3);
}
});
// CALLBACKS
uploader.onWhenAddingFileFailed = function (item /*{File|FileLikeObject}*/, filter, options) {
console.info('onWhenAddingFileFailed', item, filter, options);
};
uploader.onAfterAddingFile = function (fileItem) {
console.info('onAfterAddingFile', fileItem);
};
uploader.onAfterAddingAll = function (addedFileItems) {
console.info('onAfterAddingAll', addedFileItems);
};
uploader.onBeforeUploadItem = function (item) {
console.info('onBeforeUploadItem', item);
};
uploader.onProgressItem = function (fileItem, progress) {
console.info('onProgressItem', fileItem, progress);
};
uploader.onProgressAll = function (progress) {
console.info('onProgressAll', progress);
};
uploader.onSuccessItem = function (fileItem, response, status, headers) {
console.info('onSuccessItem', fileItem, response, status, headers);
};
uploader.onErrorItem = function (fileItem, response, status, headers) {
console.info('onErrorItem', fileItem, response, status, headers);
};
uploader.onCancelItem = function (fileItem, response, status, headers) {
console.info('onCancelItem', fileItem, response, status, headers);
};
uploader.onCompleteItem = function (fileItem, response, status, headers) {
console.info('onCompleteItem', fileItem, response, status, headers);
};
uploader.onCompleteAll = function () {
console.info('onCompleteAll');
};
console.info('uploader', uploader);
});
})();

View File

@ -0,0 +1,125 @@
(function () {
'use strict';
/**
* @ngdoc function
* @name frontendApp.controller:AdministrationSpaceCtrl
* @description
* # AdministrationSpaceCtrl
* Controller of the frontendApp
*/
angular.module('clientApp')
.controller('AdministrationSpaceCtrl', function ($scope, $state, $mdDialog, FileUploader) {
angular.extend($scope, {
logout,
deleteAbsence,
deleteTrackingSheet,
importAbsences,
importVisitSheets
})
init();
// Public methods -------------------
function logout() {
$state.go('login');
}
function deleteAbsence(groupIndex, periodIndex, absenceIndex) {
$scope.formationGroups[groupIndex].formattedAbsences[periodIndex].absences.splice(absenceIndex, 1);
}
function deleteTrackingSheet(groupIndex, trackingSheetIndex) {
$scope.formationGroups[groupIndex].trackingSheets.splice(trackingSheetIndex, 1);
}
function importVisitSheets(ev) {
$mdDialog.show({
controller: 'AdministrationDialogCtrl',
templateUrl: 'import-fiches-visite',
parent: angular.element(document.body),
targetEvent: ev,
clickOutsideToClose: true,
fullscreen: 'false',
locals : { type : 'visit'}
})
.then(function (answer) {
$scope.status = 'You said the information was "' + answer + '".';
}, function () {
$scope.status = 'You cancelled the dialog.';
});
}
function importAbsences(ev) {
$mdDialog.show({
controller: 'AdministrationDialogCtrl',
templateUrl: 'import-fiches-absences',
parent: angular.element(document.body),
targetEvent: ev,
clickOutsideToClose: true,
fullscreen: 'false',
locals : { type : 'absence'}
})
.then(function (answer) {
$scope.status = 'You said the information was "' + answer + '".';
}, function () {
$scope.status = 'You cancelled the dialog.';
});
}
// Private methods ------------------
function init() {
var formationGroups = [{
label: "Master2 ICE",
absences: [
{ id: 1, title: "Absence_Matthieu_Penchenat_P1" },
{ id: 2, title: "Absence_Renan_Husson_P1" },
{ id: 3, title: "Absence_Renan_Husson_P2" },
{ id: 1, title: "Absence_Renan_Husson_P3" },
{ id: 2, title: "Absence_Matthieu_Penchenat_P2" },
{ id: 3, title: "Absence_Matthieu_Penchenat_P3" },
{ id: 1, title: "Absence_Quentin_Rouland_P1" },
{ id: 2, title: "Absence_Quentin_Rouland_P2" },
{ id: 3, title: "Absence_Quentin_Rouland_P3" },
{ id: 1, title: "Absence_Sitan_Coulibaly_P1" },
{ id: 2, title: "Absence_Sitan_Coulibaly_P2" },
{ id: 3, title: "Absence_Sitan_Coulibaly_P3" }
],
trackingSheets: [
{ id: 3, fileName: "FicheVisite_Sitan_Coulibaly_1" },
{ id: 2, fileName: "FicheVisite_Sitan_Coulibaly_2" },
{ id: 1, fileName: "FicheVisite_Sitan_Coulibaly_3" }
]
}, {
label: "Master1 ISMAG",
absences: [
{ id: 1, title: "Absence_Matthieu_Penchenat_P1" },
{ id: 2, title: "Absence_Matthieu_Penchenat_P2" },
{ id: 3, title: "Absence_Matthieu_Penchenat_P3" }
],
trackingSheets: [
{ id: 3, fileName: "FicheVisite_Renan_Husson_1" },
{ id: 2, fileName: "FicheVisite_Renan_Husson_2" },
{ id: 1, fileName: "FicheVisite_Renan_Husson_3" }
]
}];
$scope.formationGroups = formationGroups.map(function (formationGroup) {
formationGroup.formattedAbsences = reformatAbsences(formationGroup.absences);
return formationGroup;
});
}
function reformatAbsences(absences) {
var myObj = _.groupBy(absences, function (absence) { return absence.title.split('_').pop(); });
return _.map(myObj, function (value, index) {
return { period: index, absences: value };
});
}
});
})();

View File

@ -0,0 +1,28 @@
(function () {
'use strict';
angular.module('clientApp')
.filter('fileName', function () {
return function (queue, type) {
var reg = (type === 'absence') ?/^Absence_[A-Z][a-z]*_[A-Z][a-z]*_P\d*.pdf$/ : /^Visite_[A-Z][a-z]*_[A-Z][a-z]*_\d*.pdf$/;
return queue.filter(function (item) {
return reg.test(item.file.name);
});
};
})
.filter('illegalFileNames', function () {
return function (queue, type) {
var reg = (type === 'absence') ?/^Absence_[A-Z][a-z]*_[A-Z][a-z]*_P\d*.pdf$/ : /^Visite_[A-Z][a-z]*_[A-Z][a-z]*_\d*.pdf$/;
return queue.filter(function (item) {
return !reg.test(item.file.name);
}).map(function(item) {
return item.file.name;
});
};
});
})();

View File

@ -74,4 +74,24 @@ md-tab-data{
padding: 8px;
/* border: 1px solid; */
background-color: yellowgreen;
}
}
.well {
padding: 15px;
margin: 5px;
background-color: #e0e0e0;
border: dotted 3px lightgray;
}
.note {
padding: 15px;
margin: 5px;
background-color: #a5d6a7;
}
.error {
padding: 15px;
margin: 5px;
background-color: #ef9a9a;
}

View File

@ -0,0 +1,304 @@
<div layout="column">
<md-toolbar>
<div class="md-toolbar-tools">
<h2 md-truncate flex>Bienvenue Isabelle Michu</h2>
<md-button ng-click="logout()">
Se déconnecter
</md-button>
</div>
</md-toolbar>
</div>
<div layout="row" layout-margin>
<div ng-cloak flex="100">
<md-content>
<md-tabs md-dynamic-height md-border-bottom>
<md-tab ng-repeat="formationGroup in formationGroups" label="{{formationGroup.label}}">
<div layout="row" layout-margin>
<md-card flex="50">
<md-card-title>
<md-card-title-text>
<span class="md-headline">Fiches d'absence</span>
</md-card-title-text>
</md-card-title>
<md-card-content>
<md-content flex layout-padding>
<div style="height: 350px; overflow: auto">
<div ng-repeat="formattedAbsence in formationGroup.formattedAbsences">
<md-subheader class="md-no-sticky">Période {{formattedAbsence.period}}</md-subheader>
<md-list-item ng-repeat="absence in formattedAbsence.absences">
<p>{{absence.title}}</p>
<ng-md-icon icon="delete" style="fill: grey" size="24" ng-click="deleteAbsence($parent.$parent.$index, $parent.$index, $index)"></ng-md-icon>
</md-list-item>
</div>
</div>
<br />
<center>
<md-button class="md-raised md-primary" ng-click="importAbsences($event)">Importer des fiches d'absences</md-button>
</center>
</md-content>
</md-card-content>
</md-card>
<md-card flex="50">
<md-card-title>
<md-card-title-text>
<span class="md-headline">Fiches de visite</span>
</md-card-title-text>
</md-card-title>
<md-card-content>
<md-content flex layout-padding>
<div style="height: 350px; overflow: auto">
<md-list-item ng-repeat="sheet in formationGroup.trackingSheets">
<p>{{sheet.fileName}}</p>
<ng-md-icon icon="delete" style="fill: grey" size="24" ng-click="deleteTrackingSheet($parent.$index, $index)"></ng-md-icon>
</md-list-item>
</div>
<br />
<center>
<md-button class="md-raised md-primary" ng-click="importVisitSheets($event)">Importer des fiches de visite</md-button>
</center>
</md-content>
</md-card-content>
</md-card>
</div>
</md-tab>
</md-tabs>
</md-content>
</div>
</div>
<script type="text/ng-template" id="import-fiches-absences">
<md-dialog aria-label="Importer des fiches d'absences">
<form ng-cloak>
<md-toolbar>
<div class="md-toolbar-tools">
<h2>Importer des fiches d'absences</h2>
</div>
</md-toolbar>
<md-dialog-content>
<div class="md-dialog-content">
<div layout="row">
<div flex>
<h3>Importer des fiches d'absences</h3>
<input type="file" nv-file-select="" accept=".pdf" uploader="uploader" multiple /><br/><br/>
<p class="note">
<ng-md-icon icon="warning" size="20"></ng-md-icon>
Note d'utilisation : chaque fiche d'absence doit respecter une règle de nommage.<br/> Nom
de fichier : Absence_Prenom_Nom_PN.pdf<br/>
<i>Le N de PN étant un numéro - exemple : (P1, P2, P3, etc.)</i>
</p>
<div ng-if="uploader.queue.length !== 0">
<h3>Liste des documents : </h3>
<p>Nombre de documents : {{ uploader.queue.length }}</p>
<div ng-if="areThereIllegalFiles()" style="background-color: #ef9a9a; padding: 2px 10px 2px 10px;margin: 10px 0 10px 0">
<p>
Les documents suivants ne respectent pas la règle de nommage :
</p>
<ul>
<li ng-repeat="fileName in uploader.queue | illegalFileNames:'absence'">{{fileName}}</li>
</ul>
</div>
<div ng-if="!allDocumentsAreIllegal()">
<table class="bordered">
<thead>
<tr>
<th width="50%">Nom</th>
<th ng-show="uploader.isHTML5">Taille</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in uploader.queue | fileName:'absence'">
<td><strong>{{ item.file.name }}</strong></td>
<td ng-show="uploader.isHTML5" nowrap>{{ item.file.size/1024/1024|number:2 }} MB</td>
<td class="text-center">
<span ng-show="item.isSuccess">
<ng-md-icon icon="done" size="24"></ng-md-icon>
</span>
<span ng-show="item.isCancel">
<ng-md-icon icon="cancel" size="24"></ng-md-icon>
</span>
<span ng-show="item.isError">
<ng-md-icon icon="remove_circle_outline" size="24"></ng-md-icon>
</span>
</td>
<td nowrap>
<md-button type="button" class="md-raised md-primary" ng-click="item.upload()" ng-disabled="item.isReady || item.isUploading || item.isSuccess">
<ng-md-icon icon="file_upload" size="24"></ng-md-icon> Charger
</md-button>
<md-button type="button" class="md-raised" ng-click="item.cancel()" ng-disabled="!item.isUploading">
<ng-md-icon icon="cancel" size="24"></ng-md-icon> Annuler
</md-button>
<md-button type="button" class="md-raised md-warn" ng-click="item.remove()">
<ng-md-icon icon="remove_circle_outline" size="24"></ng-md-icon> Supprimer
</md-button>
</td>
</tr>
</tbody>
</table>
<div style='margin-top : 40px'>
<div>
Niveau de progression :
<md-progress-linear md-mode="determinate" value="{{uploader.progress}}"></md-progress-linear>
</div>
<md-button type="button" class="md-raised md-primary" ng-click="uploader.uploadAll()" ng-disabled="!uploader.getNotUploadedItems().length">
<ng-md-icon icon="file_upload" size="24"></ng-md-icon> Tout charger
</md-button>
<md-button type="button" class="md-raised" ng-click="uploader.cancelAll()" ng-disabled="!uploader.isUploading">
<ng-md-icon icon="cancel" size="24"></ng-md-icon> Tout annuler
</md-button>
<md-button type="button" class="md-raised md-warn" ng-click="uploader.clearQueue()" ng-disabled="!uploader.queue.length">
<ng-md-icon icon="remove_circle_outline" size="24"></ng-md-icon> Tout supprimer
</md-button>
</div>
</div>
</div>
</div>
</div>
</div>
</md-dialog-content>
<md-dialog-actions layout="row">
<span flex></span>
<md-button ng-click="answer('useful')">
Fermer
</md-button>
</md-dialog-actions>
</form>
</md-dialog>
</script>
<script type="text/ng-template" id="import-fiches-visite">
<md-dialog aria-label="Importer des fiches de visite">
<form ng-cloak>
<md-toolbar>
<div class="md-toolbar-tools">
<h2>Importer des fiches de visite</h2>
</div>
</md-toolbar>
<md-dialog-content>
<div class="md-dialog-content">
<div layout="row">
<div flex>
<h3>Importer des fiches de visite</h3>
<input type="file" nv-file-select="" accept=".pdf" uploader="uploader" multiple /><br/><br/>
<p class="note">
<ng-md-icon icon="warning" size="20"></ng-md-icon>
Note d'utilisation : chaque fiche de visite doit respecter une règle de nommage.<br/> Nom
de fichier : Visite_Prenom_Nom_N.pdf<br/>
<i>Le N étant un numéro.</i>
</p>
<div ng-if="uploader.queue.length !== 0">
<h3>Liste des documents : </h3>
<p>Nombre de documents : {{ uploader.queue.length }}</p>
<div ng-if="areThereIllegalFiles()" style="background-color: #ef9a9a; padding: 2px 10px 2px 10px;margin: 10px 0 10px 0">
<p>
Les documents suivants ne respectent pas la règle de nommage :
</p>
<ul>
<li ng-repeat="fileName in uploader.queue | illegalFileNames:'visit'">{{fileName}}</li>
</ul>
</div>
<div ng-if="!allDocumentsAreIllegal()">
<table class="bordered">
<thead>
<tr>
<th width="50%">Nom</th>
<th ng-show="uploader.isHTML5">Taille</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in uploader.queue | fileName:'visit'">
<td><strong>{{ item.file.name }}</strong></td>
<td ng-show="uploader.isHTML5" nowrap>{{ item.file.size/1024/1024|number:2 }} MB</td>
<td class="text-center">
<span ng-show="item.isSuccess">
<ng-md-icon icon="done" size="24"></ng-md-icon>
</span>
<span ng-show="item.isCancel">
<ng-md-icon icon="cancel" size="24"></ng-md-icon>
</span>
<span ng-show="item.isError">
<ng-md-icon icon="remove_circle_outline" size="24"></ng-md-icon>
</span>
</td>
<td nowrap>
<md-button type="button" class="md-raised md-primary" ng-click="item.upload()" ng-disabled="item.isReady || item.isUploading || item.isSuccess">
<ng-md-icon icon="file_upload" size="24"></ng-md-icon> Charger
</md-button>
<md-button type="button" class="md-raised" ng-click="item.cancel()" ng-disabled="!item.isUploading">
<ng-md-icon icon="cancel" size="24"></ng-md-icon> Annuler
</md-button>
<md-button type="button" class="md-raised md-warn" ng-click="item.remove()">
<ng-md-icon icon="remove_circle_outline" size="24"></ng-md-icon> Supprimer
</md-button>
</td>
</tr>
</tbody>
</table>
<div style='margin-top : 40px'>
<div>
Niveau de progression :
<md-progress-linear md-mode="determinate" value="{{uploader.progress}}"></md-progress-linear>
</div>
<md-button type="button" class="md-raised md-primary" ng-click="uploader.uploadAll()" ng-disabled="!uploader.getNotUploadedItems().length">
<ng-md-icon icon="file_upload" size="24"></ng-md-icon> Tout charger
</md-button>
<md-button type="button" class="md-raised" ng-click="uploader.cancelAll()" ng-disabled="!uploader.isUploading">
<ng-md-icon icon="cancel" size="24"></ng-md-icon> Tout annuler
</md-button>
<md-button type="button" class="md-raised md-warn" ng-click="uploader.clearQueue()" ng-disabled="!uploader.queue.length">
<ng-md-icon icon="remove_circle_outline" size="24"></ng-md-icon> Tout supprimer
</md-button>
</div>
</div>
</div>
</div>
</div>
</div>
</md-dialog-content>
<md-dialog-actions layout="row">
<span flex></span>
<md-button ng-click="answer('useful')">
Fermer
</md-button>
</md-dialog-actions>
</form>
</md-dialog>
</script>

View File

@ -8,6 +8,8 @@
</md-card-title-text>
</md-card-title>
<md-card-content>
<md-button ui-sref="administrationSpace">Log to administration</md-button>
<p class="p-home">
The titles of Washed Out's breakthrough song and the first single from Paracosm share the two most important words in Ernest
Greene's musical language: feel it. It's a simple request, as well...

View File

@ -13,37 +13,209 @@
</div>
<div layout="row" layout-align="center none">
<div ng-controller="AppCtrl" class="sample" layout="column" ng-cloak>
<md-content class="md-padding">
<md-tabs md-selected="selectedIndex" md-border-bottom md-autoselect>
<md-tab ng-repeat="tab in tabs"
ng-disabled="tab.disabled"
label="{{tab.title}}">
<div class="demo-tab tab{{$index%4}}" style="padding: 25px; text-align: center;">
<div ng-bind="tab.content"></div>
<br/>
<md-button class="md-primary md-raised" ng-click="removeTab( tab )" ng-disabled="tabs.length <= 1">Remove Tab</md-button>
<md-content flex="80">
<div ng-cloak>
<md-content>
<md-tabs md-dynamic-height md-border-bottom>
<md-tab label="périodes">
<md-content class="md-padding">
<div layout="row" layout-align="end">
<md-button class="md-raised" ng-click="exportBooklet()">Exporter le livret</md-button>
</div>
<md-card ng-repeat="period in periods">
<md-card-title>
<md-card-title-text>
<h2 class="md-display-1">Période {{period.number}}</h2>
</md-card-title-text>
</md-card-title>
<md-card-content>
<div layout="column" layout-fill>
<div flex class="green darken-2">
<h3 class="md-headline" style="padding-left : 10px">
Université
<md-button class="md-icon-button" ng-click="toggleAccordion(period.university.icon, 'false', $index)" aria-label="call">
<ng-md-icon icon="{{period.university.icon}}" style="fill: blue" size="24"></ng-md-icon>
</md-button>
</h3>
<md-content flex layout-padding ng-if="isOpenAccordion(period.university.icon)">
<p>Lorem ipsum dolor sit amet, ne quod novum mei. Sea omnium invenire mediocrem at, in lobortis conclusionemque
nam. Ne deleniti appetere reprimique pro, inani labitur disputationi te sed. At vix sale omnesque,
id pro labitur reformidans accommodare, cum labores honestatis eu. Nec quem lucilius in, eam praesent
reformidans no. Sed laudem aliquam ne.</p><br/>
<md-input-container class="md-block">
<label>Commentaire de période</label>
<textarea ng-model="period.university.comment" md-maxlength="150" rows="5" md-select-on-focus></textarea>
</md-input-container>
<div layout="row" layout-align="end">
<md-button class="md-raised">Enregistrer</md-button>
</div>
</md-content>
</div>
<div flex class="green darken-3">
<h3 class="md-headline" style="padding-left : 10px">
Entreprise
<md-button class="md-icon-button" ng-click="toggleAccordion(period.company.icon, 'true', $index)" aria-label="call">
<ng-md-icon icon="{{period.company.icon}}" style="fill: blue" size="24"></ng-md-icon>
</md-button>
</h3>
<md-content flex layout-padding ng-if="isOpenAccordion(period.company.icon)">
<p>Lorem ipsum dolor sit amet, ne quod novum mei. Sea omnium invenire mediocrem at, in lobortis conclusionemque
nam. Ne deleniti appetere reprimique pro, inani labitur disputationi te sed. At vix sale omnesque,
id pro labitur reformidans accommodare, cum labores honestatis eu. Nec quem lucilius in, eam praesent
reformidans no. Sed laudem aliquam ne.</p>
<md-input-container class="md-block">
<label>Commentaire de période</label>
<textarea ng-model="period.company.comment" md-maxlength="150" rows="5" md-select-on-focus></textarea>
</md-input-container>
<div layout="row" layout-align="end">
<md-button class="md-raised">Enregistrer</md-button>
</div>
</md-content>
</div>
</div>
</md-card-content>
</md-card>
</md-content>
</md-tab>
<md-tab label="données administratives">
<md-content class="md-padding">
<md-content layout-padding>
<form name="projectForm">
<md-card>
<md-card-title>
<md-card-title-text>
<h3 class="md-headline">Informations personnelles</h3>
</md-card-title-text>
</md-card-title>
<md-card-content>
<div layout="row">
<md-input-container flex="50">
<label>Prénom</label>
<input required name="studentFirstName" ng-model="studentFirstName">
</md-input-container>
<md-input-container flex="50">
<label>Nom</label>
<input required name="studentLastName" ng-model="studentLastName">
</md-input-container>
</div>
<div layout="row">
<md-input-container flex="50">
<label>Type de contrat / d'engagement</label>
<md-select name="type" ng-model="contractType" required>
<md-option value="Apprentissage">Apprentissage</md-option>
<md-option value="Professionnalisation">Professionnalisation</md-option>
<md-option value="Stage">Stage</md-option>
</md-select>
</md-input-container>
<md-input-container flex="25">
<label>Début de contrat</label>
<md-datepicker ng-model="beginContractDate"></md-datepicker>
</md-input-container>
<md-input-container flex="25">
<label>Fin de contrat</label>
<md-datepicker ng-model="endContractDate"></md-datepicker>
</md-input-container>
</div>
<div layout="row">
<md-input-container flex="50">
<label>Email</label>
<input required type="email" name="studentEmail" ng-model="studentEmail" />
</md-input-container>
<md-input-container flex="50">
<label>Téléphone</label>
<input required type="text" name="studentPhoneNumber" ng-model="studentPhoneNumber" />
</md-input-container>
</div>
</md-card-content>
</md-card>
<md-card>
<md-card-title>
<md-card-title-text>
<h3 class="md-headline">Tuteur pédagogique</h3>
</md-card-title-text>
</md-card-title>
<md-card-content>
<md-input-container class="md-block">
<label>Email</label>
<input required type="email" name="universityEmail" ng-model="universityEmail" />
</md-input-container>
</md-card-content>
</md-card>
<md-card>
<md-card-title>
<md-card-title-text>
<h3 class="md-headline">Tuteur entreprise</h3>
</md-card-title-text>
</md-card-title>
<md-card-content>
<div layout="row">
<md-input-container flex="50">
<label>Prénom</label>
<input required name="companyFirstName" ng-model="companyFirstName">
</md-input-container>
<md-input-container flex="50">
<label>Nom</label>
<input required name="companyLastName" ng-model="companyLastName">
</md-input-container>
</div>
<div layout="row">
<md-input-container flex="50">
<label>Nom de l'entreprise</label>
<input name="companyName" ng-model="companyName">
</md-input-container>
<md-input-container flex="50">
<label>Lieu de l'alternance</label>
<input name="companyAddress" ng-model="companyAddress">
</md-input-container>
</div>
<md-input-container class="md-block">
<label>Email</label>
<input required type="email" name="companyEmail" ng-model="companyEmail" />
</md-input-container>
</md-card-content>
</md-card>
<div layout="row" layout-align="end">
<md-button class="md-raised">Enregistrer</md-button>
</div>
</form>
</md-content>
</md-tab>
</md-tabs>
</md-content>
</div>
</md-tab>
</md-tabs>
</md-content>
<form ng-submit="addTab(tTitle,tContent)" layout="column" class="md-padding" style="padding-top: 0;">
<div layout="row" layout-sm="column">
<div flex style="position: relative;">
<h2 class="md-subhead" style="position: absolute; bottom: 0; left: 0; margin: 0; font-weight: 500; text-transform: uppercase; line-height: 35px; white-space: nowrap;">Add a new Tab:</h2>
</div>
<md-input-container>
<label for="label">Label</label>
<input type="text" id="label" ng-model="tTitle">
</md-input-container>
<md-input-container>
<label for="content">Content</label>
<input type="text" id="content" ng-model="tContent">
</md-input-container>
<md-button class="add-tab md-primary md-raised" ng-disabled="!tTitle || !tContent" type="submit" style="margin-right: 0;">Add Tab</md-button>
</div>
</form>
</div>
</div>
</md-content>
</div>

View File

@ -8,7 +8,9 @@
"angular-sanitize": "^1.4.0",
"angular-material": "^1.1.3",
"angular-ui-router": "^0.4.2",
"angular-material-icons": "^0.7.1"
"angular-material-icons": "^0.7.1",
"underscore": "^1.8.3",
"angular-file-upload": "^2.5.0"
},
"devDependencies": {
"angular-mocks": "^1.4.0"

View File

@ -29,6 +29,8 @@ module.exports = function(config) {
'bower_components/angular-material/angular-material.js',
'bower_components/angular-ui-router/release/angular-ui-router.js',
'bower_components/angular-material-icons/angular-material-icons.min.js',
'bower_components/underscore/underscore.js',
'bower_components/angular-file-upload/dist/angular-file-upload.min.js',
'bower_components/angular-mocks/angular-mocks.js',
// endbower
'app/scripts/**/*.js',