diff --git a/api/src/storage/queries.js b/api/src/storage/queries.js index 1d756af7..45e87dc0 100644 --- a/api/src/storage/queries.js +++ b/api/src/storage/queries.js @@ -48,7 +48,7 @@ function listWaitingInvitations(userEmail) { { $unwind: '$project' }, { $project: { - 'projectId': 1, 'email': 1, 'accepted': 1, + 'projectId': 1, 'email': 1, 'accepted': 1, 'dataEntry': 1, 'project.owner': 1, 'project.country': 1, 'project.name': 1, 'project.start': 1, 'project.end': 1 } } @@ -61,7 +61,7 @@ function listProjectInvitations(userEmail, projectId) { { $lookup: { from: 'project', localField: 'projectId', foreignField: '_id', as: 'project' } }, { $unwind: '$project' }, { $match: { $or: [{ email: userEmail }, { 'project.owner': userEmail }] } }, - { $project: { 'projectId': 1, 'email': 1, 'accepted': 1 } } + { $project: { 'projectId': 1, 'email': 1, 'accepted': 1, 'dataEntry': 1, } } ]); } @@ -71,7 +71,7 @@ async function getInvitation(userEmail, id) { { $lookup: { from: 'project', localField: 'projectId', foreignField: '_id', as: 'project' } }, { $unwind: '$project' }, { $match: { $or: [{ email: userEmail }, { 'project.owner': userEmail }] } }, - { $project: { 'projectId': 1, 'email': 1, 'accepted': 1 } } + { $project: { 'projectId': 1, 'email': 1, 'accepted': 1, 'dataEntry': 1, } } ]).next(); } diff --git a/api/src/storage/schema/invitation.js b/api/src/storage/schema/invitation.js index 45fd2412..990a82b4 100644 --- a/api/src/storage/schema/invitation.js +++ b/api/src/storage/schema/invitation.js @@ -1,17 +1,42 @@ module.exports = { - "type": "object", - "additionalProperties": false, - "required": [ + definitions: require('./_definitions'), + type: "object", + additionalProperties: false, + required: [ "email", "accepted" ], - "properties": { - "email": { - "type": "string", - "format": "email" + properties: { + projectId: { + type: "string", + match: "^[0-9a-z]{24}$" }, - "accepted": { - "type": "boolean" + email: { + type: "string", + format: "email" + }, + accepted: { + type: "boolean" + }, + dataEntry: { + type: "object", + required: ["dataSourceIds", "siteIds"], + properties: { + dataSourceIds: { + type: "array", + uniqueItems: true, + items: { + $ref: "#/definitions/uuid" + } + }, + siteIds: { + type: "array", + uniqueItems: true, + items: { + $ref: "#/definitions/uuid" + } + } + } } } -} \ No newline at end of file +}; diff --git a/frontend/src/components/pages/input-home/project-input-home.html b/frontend/src/components/pages/input-home/project-input-home.html index ad2d779b..aae039ba 100644 --- a/frontend/src/components/pages/input-home/project-input-home.html +++ b/frontend/src/components/pages/input-home/project-input-home.html @@ -10,36 +10,35 @@ -Avancement des saisies +
+ Avancement des saisies - - - - - - - - - - - - - - - - - - -
Formulaire#
- - - {{dataSource.name|maxLength:30}} - - - - {{$ctrl.status[dataSource.id].total}} - - -
\ No newline at end of file + + + + + + + + + + + + + + + +
Formulaire#
+ + + {{dataSource.name|maxLength:30}} + + + + {{$ctrl.status[dataSource.id].total}} + + +
+
\ No newline at end of file diff --git a/frontend/src/components/pages/input-home/project-input-home.js b/frontend/src/components/pages/input-home/project-input-home.js index 6c5141d3..55433898 100644 --- a/frontend/src/components/pages/input-home/project-input-home.js +++ b/frontend/src/components/pages/input-home/project-input-home.js @@ -21,29 +21,42 @@ module.config($stateProvider => { module.component(__componentName, { bindings: { project: '<', + invitations: '<', users: '<' }, template: require(__templatePath), controller: class ProjectInputHomeController { - constructor($scope) { + constructor($scope, $rootScope) { "ngInject"; this.$scope = $scope; + this.$rootScope = $rootScope; } async $onChanges(changes) { - this.status = {}; + const myEmail = this.$rootScope.profile.email; + const myInvitation = this.invitations.find(i => i.email === myEmail); // A datasource is active if we can perform data entry in at least one site. this.activeDataSources = this.project.forms.filter(ds => { + // FIXME this was copy pasted from input-menu + const mySites = myInvitation ? myInvitation.dataEntry.siteIds : this.project.entities.map(s => s.id); + const myDss = myInvitation ? myInvitation.dataEntry.dataSourceIds : this.project.forms.map(ds => ds.id); + return ds.active && ds.elements.some(variable => variable.active) - && ds.entities.some(siteId => this.project.entities.find(site => site.id == siteId).active) + && myDss.includes(ds.id) + && ds.entities.some(siteId => + this.project.entities.find(site => site.id == siteId).active && + mySites.includes(siteId) + ); }); + this.status = {}; this.activeDataSources.forEach(async ds => { - this.status[ds.id] = await Input.fetchFormShortStatus(this.project, ds.id); + const siteIds = myInvitation ? myInvitation.dataEntry.siteIds : null; + this.status[ds.id] = await Input.fetchFormShortStatus(this.project, ds.id, siteIds); this.$scope.$apply(); }); } diff --git a/frontend/src/components/pages/input-list/project-input-list.js b/frontend/src/components/pages/input-list/project-input-list.js index 1017d15e..5195f438 100644 --- a/frontend/src/components/pages/input-list/project-input-list.js +++ b/frontend/src/components/pages/input-list/project-input-list.js @@ -23,6 +23,7 @@ module.component(__componentName, { bindings: { 'project': '<', 'dataSourceId': '<', + 'invitations': '<' }, template: require(__templatePath), @@ -63,14 +64,21 @@ module.component(__componentName, { this.dataSource = this.project.forms.find(ds => ds.id === this.dataSourceId); // Define sites (depending on user permissions) - this.sites = this.project.entities.filter(e => e.active && this.dataSource.entities.includes(e.id)); + const myInvitation = this.invitations.find(i => i.email === this.userEmail); + this.sites = this.project.entities.filter(e => + e.active && this.dataSource.entities.includes(e.id) && + (!myInvitation || myInvitation.dataEntry.siteIds.includes(e.id)) + ); this.loading = true; this.load(); } async load() { - this.inputsStatus = await Input.fetchFormStatus(this.project, this.dataSourceId); + const myInvitation = this.invitations.find(i => i.email === this.userEmail); + const siteIds = myInvitation ? myInvitation.dataEntry.siteIds : null; + + this.inputsStatus = await Input.fetchFormStatus(this.project, this.dataSourceId, siteIds); // Those list tell which rows should be displayed. this.visibleStatus = Object.keys(this.inputsStatus).slice(0, 20); diff --git a/frontend/src/components/pages/input-menu/project-input-menu.html b/frontend/src/components/pages/input-menu/project-input-menu.html index b81f27b9..b2aa1aea 100644 --- a/frontend/src/components/pages/input-menu/project-input-menu.html +++ b/frontend/src/components/pages/input-menu/project-input-menu.html @@ -11,7 +11,7 @@ -
+

@@ -26,11 +26,6 @@

{{dataSource.name}} - - - - -
diff --git a/frontend/src/components/pages/input-menu/project-input-menu.js b/frontend/src/components/pages/input-menu/project-input-menu.js index b2de0968..9afb2aba 100644 --- a/frontend/src/components/pages/input-menu/project-input-menu.js +++ b/frontend/src/components/pages/input-menu/project-input-menu.js @@ -26,24 +26,33 @@ module.component(__componentName, { controller: class ProjectInputMenuController { - constructor($state, $stateParams) { + constructor($state, $stateParams, $rootScope) { "ngInject"; + this.$rootScope = $rootScope; this.$state = $state; this.$stateParams = $stateParams; } $onChanges() { + const myEmail = this.$rootScope.profile.email; + const myInvitation = this.invitations.find(i => i.email === myEmail); + // A datasource is active if we can perform data entry in at least one site. this.activeDataSources = this.project.forms.filter(ds => { + const mySites = myInvitation ? myInvitation.dataEntry.siteIds : this.project.entities.map(s => s.id); + const myDss = myInvitation ? myInvitation.dataEntry.dataSourceIds : this.project.forms.map(ds => ds.id); + return ds.active && ds.elements.some(variable => variable.active) - && ds.entities.some(siteId => this.project.entities.find(site => site.id == siteId).active) + && myDss.includes(ds.id) + && ds.entities.some(siteId => + this.project.entities.find(site => site.id == siteId).active && + mySites.includes(siteId) + ); }); } } }); - export default module.name; - diff --git a/frontend/src/components/pages/structure-menu/project-edit-menu.html b/frontend/src/components/pages/structure-menu/project-edit-menu.html index b04b8aab..4f0bb9cf 100644 --- a/frontend/src/components/pages/structure-menu/project-edit-menu.html +++ b/frontend/src/components/pages/structure-menu/project-edit-menu.html @@ -55,7 +55,7 @@

- {{$ctrl.invitations.length}} diff --git a/frontend/src/components/pages/structure-user/project-user-list.html b/frontend/src/components/pages/structure-user/project-user-list.html index 2fd74c00..39c060db 100644 --- a/frontend/src/components/pages/structure-user/project-user-list.html +++ b/frontend/src/components/pages/structure-user/project-user-list.html @@ -3,34 +3,54 @@ -
- - {{invitation.email}} - -
- - - + + {{invitation.email}} + +
+ Invitation acceptée: + {{invitation.accepted}} +
+ + Autorisations de saisie: + +
+ Lieux de collecte: + + +
+ +
+ Sources de données: + + +
+ +
+ + + + + +
+ + -
- - - - - -
+
- - +
+ + +
diff --git a/frontend/src/components/pages/structure-user/project-user-list.js b/frontend/src/components/pages/structure-user/project-user-list.js index 9d97e6f0..b3c4fc3b 100644 --- a/frontend/src/components/pages/structure-user/project-user-list.js +++ b/frontend/src/components/pages/structure-user/project-user-list.js @@ -11,8 +11,8 @@ const module = angular.module(__moduleName, [uiRouter, 'ng-sortable', mtProjectU module.config($stateProvider => { - $stateProvider.state('project.config.user_list', { - url: '/users', + $stateProvider.state('project.config.invitation_list', { + url: '/invitations', component: __componentName, }); }); @@ -52,7 +52,8 @@ module.component(__componentName, { if (oldIvt) { if (newIvt) { // Replace - const response = await axios.put(`/invitation/${invitation._id}`, newIvt); + const { _id, ...body } = newIvt; + const response = await axios.put(`/invitation/${_id}`, body); this.invitations.splice( this.invitations.indexOf(oldIvt), diff --git a/frontend/src/components/pages/structure-user/project-user-modal.html b/frontend/src/components/pages/structure-user/project-user-modal.html index 439fa73a..7c59098f 100644 --- a/frontend/src/components/pages/structure-user/project-user-modal.html +++ b/frontend/src/components/pages/structure-user/project-user-modal.html @@ -1,36 +1,35 @@ - - -