Commit 205d720f authored by thomas craipeau's avatar thomas craipeau
Browse files

start forms et annswers

parent 389b3894
......@@ -29,4 +29,5 @@ npm-debug.log
package-lock.json
/google-services.json
/GoogleService-Info.plist
/.deploy/
\ No newline at end of file
/.deploy/
/.deploy-node14/
\ No newline at end of file
......@@ -86,6 +86,13 @@
"No longer participate": "No longer participate",
"Action Finished": "Action Finished",
"In progress": "In progress",
"progress": "In progress",
"vote": "Under evaluation",
"finance": "Current financing ",
"call": "Call for participation",
"newaction": "New proposition",
"projectstate": "Project",
"suspend": "Suspended",
"Historical": "Historical",
"Add credit line": "Add credit line",
"Tibillet card transfer": "Tibillet card transfer",
......@@ -134,7 +141,9 @@
"Personal Actions": "Personal Actions",
"Notifications": "Notifications",
"Sub-organizations": "Sub-organizations",
"Milestones": "Milestones"
"Milestones": "Milestones",
"DetailForm": "Details of the call for projects",
"Anwswers": "List of proposals"
},
"contributor to validate": "__count__ contributor to validate",
"contributor to validate_plural": "__count__ contributors to validate",
......
......@@ -86,6 +86,13 @@
"No longer participate": "Ne plus participer",
"Action Finished": "Action Fini",
"In progress": "En cours",
"progress": "En cours",
"vote": "En évaluation",
"finance": "En financement",
"call": "Appel à participation",
"newaction": "Nouvelle proposition",
"projectstate": "En projet",
"suspend": "Suspendu",
"Historical": "Historiques",
"Add credit line": "Ajout ligne crédit",
"Tibillet card transfer": "Transfert carte tibillet",
......@@ -134,7 +141,9 @@
"Personal Actions": "Actions Perso",
"Notifications": "Notifications",
"Sub-organizations": "Sous-organisations",
"Milestones": "Jalons"
"Milestones": "Jalons",
"DetailForm": "Détails de l'appel à projets",
"Anwswers": "Liste des propositions"
},
"contributor to validate": "__count__ contributeur à valider",
"contributor to validate_plural": "__count__ contributeurs à valider",
......
import { Mongo } from 'meteor/mongo';
// eslint-disable-next-line import/prefer-default-export
export const Answers = new Mongo.Collection('answers', { idGeneration: 'MONGO' });
import { Mongo } from 'meteor/mongo';
// eslint-disable-next-line import/prefer-default-export
export const Forms = new Mongo.Collection('forms', { idGeneration: 'MONGO' });
......@@ -267,10 +267,10 @@ Actions.helpers({
},
projectDayHour() {
// return moment(this.startDate).format(' ddd Do MMM à HH:mm ');
return moment(this.startDate).format(' ddd Do MMM LT ');
return moment(this.startDate).format(' ddd D MMM LT ');
},
projectDay() {
return moment(this.startDate).format(' ddd Do MMM ');
return moment(this.startDate).format(' ddd D MMM ');
},
projectDayHourEnd() {
if (this.projectDay() === this.projectDayEnd()) {
......@@ -279,7 +279,7 @@ Actions.helpers({
return moment(this.endDate).format('LLLL');
},
projectDayEnd() {
return moment(this.endDate).format(' ddd Do MMM ');
return moment(this.endDate).format(' ddd D MMM ');
},
projectDuration() {
const startDate = moment(this.startDate);
......
/* eslint-disable meteor/no-session */
/* global Session */
import { Meteor } from 'meteor/meteor';
import { Mongo } from 'meteor/mongo';
import { moment } from 'meteor/momentjs:moment';
import { _ } from 'meteor/underscore';
// schemas
import { Answers } from '../collection/answers.js';
import { Citoyens } from '../collection/citoyens.js';
import {
isAdminArray, arrayOrganizerParent, queryLink, queryLinkToBeValidated, queryOptions, arrayLinkProper, arrayLinkProperNoObject, nameToCollection,
} from '../helpers.js';
if (Meteor.isClient) {
import { Chronos } from '../client/chronos.js';
Answers.helpers({
isStartDate() {
if (this.startDate) {
// todo date pas correct en base
const start = moment(this.startDate, 'DD/MM/YYYY').toDate();
return Chronos.moment(start).isBefore(); // True
}
return false;
},
isNotStartDate() {
if (this.startDate) {
const start = moment(this.startDate, 'DD/MM/YYYY').toDate();
return Chronos.moment().isBefore(start); // True
}
return false;
},
isEndDate() {
if (this.endDate) {
const end = moment(this.endDate, 'DD/MM/YYYY').toDate();
return Chronos.moment(end).isBefore(); // True
}
return false;
},
isNotEndDate() {
if (this.endDate) {
const end = moment(this.endDate, 'DD/MM/YYYY').toDate();
return Chronos.moment().isBefore(end); // True
}
return false;
},
});
} else {
Answers.helpers({
isEndDate() {
if (this.endDate) {
const end = moment(this.endDate, 'DD/MM/YYYY').toDate();
return moment(end).isBefore(); // True
}
return false;
},
isNotEndDate() {
if (this.endDate) {
const end = moment(this.endDate, 'DD/MM/YYYY').toDate();
return moment().isBefore(end); // True
}
return false;
},
});
}
Answers.helpers({
isCreator() {
return this.user === Meteor.userId();
},
creatorProfile() {
return Citoyens.findOne({ _id: new Mongo.ObjectID(this.user) });
},
scopeVar() {
return 'answers';
},
scopeEdit() {
return 'answersEdit';
},
listScope() {
return 'listAnswers';
},
isStart() {
const start = moment(this.startDate, 'DD/MM/YYYY').toDate();
return moment(start).isBefore(); // True
},
formatStartDate() {
// todo : utilisé local
// return moment(this.startDate).format('DD/MM/YYYY HH:mm');
return moment(this.startDate, 'DD/MM/YYYY').format('L LT');
},
formatEndDate() {
// todo : utilisé local
// return moment(this.endDate).format('DD/MM/YYYY HH:mm');
return moment(this.endDate, 'DD/MM/YYYY').format('L LT');
},
formatStartDateIso() {
// todo : utilisé local
// return moment(this.startDate).format('DD/MM/YYYY HH:mm');
return moment(this.startDate, 'DD/MM/YYYY');
},
formatEndDateIso() {
// todo : utilisé local
// return moment(this.endDate).format('DD/MM/YYYY HH:mm');
return moment(this.endDate, 'DD/MM/YYYY');
},
duration() {
const a = moment(this.startDate, 'DD/MM/YYYY');
const b = moment(this.endDate, 'DD/MM/YYYY');
const diffInMs = b.diff(a); // 86400000 milliseconds
// const diffInDays = b.diff(a, 'days'); // 1 day
const diffInDayText = moment.duration(diffInMs).humanize();
return diffInDayText;
},
createdFormat() {
const inputUnix = moment.unix(this.created);
return moment(inputUnix).format('L LT');
},
});
......@@ -30,7 +30,6 @@ if (Meteor.isClient) {
import { Chronos } from '../client/chronos.js';
Events.helpers({
isStartDate() {
if (this.startDate) {
const start = moment(this.startDate).toDate();
......@@ -278,7 +277,7 @@ Events.helpers({
formatEndDate() {
// todo : utilisé local
// return moment(this.endDate).format('DD/MM/YYYY HH:mm');
return moment(this.startDate).format('L LT');
return moment(this.endDate).format('L LT');
},
typeValue() {
const eventTypes = Lists.findOne({ name: 'eventTypes' });
......
/* eslint-disable meteor/no-session */
/* global Session */
import { Meteor } from 'meteor/meteor';
import { Mongo } from 'meteor/mongo';
import { moment } from 'meteor/momentjs:moment';
import { _ } from 'meteor/underscore';
// schemas
import { Forms } from '../collection/forms.js';
import { Citoyens } from '../collection/citoyens.js';
import { Answers } from '../collection/answers.js';
import {
isAdminArray, arrayOrganizerParent, searchQueryAnswers, searchQuerySort, queryLink, queryLinkToBeValidated, queryOptions, arrayLinkProper, arrayLinkProperNoObject, nameToCollection,
} from '../helpers.js';
if (Meteor.isClient) {
import { Chronos } from '../client/chronos.js';
Forms.helpers({
isStartDate() {
if (this.startDate) {
// todo date pas correct en base
const start = moment(this.startDate, 'DD/MM/YYYY').toDate();
return Chronos.moment(start).isBefore(); // True
}
return false;
},
isNotStartDate() {
if (this.startDate) {
const start = moment(this.startDate, 'DD/MM/YYYY').toDate();
return Chronos.moment().isBefore(start); // True
}
return false;
},
isEndDate() {
if (this.endDate) {
const end = moment(this.endDate, 'DD/MM/YYYY').toDate();
return Chronos.moment(end).isBefore(); // True
}
return false;
},
isNotEndDate() {
if (this.endDate) {
const end = moment(this.endDate, 'DD/MM/YYYY').toDate();
return Chronos.moment().isBefore(end); // True
}
return false;
},
});
} else {
Forms.helpers({
isEndDate() {
if (this.endDate) {
const end = moment(this.endDate, 'DD/MM/YYYY').toDate();
return moment(end).isBefore(); // True
}
return false;
},
isNotEndDate() {
if (this.endDate) {
const end = moment(this.endDate, 'DD/MM/YYYY').toDate();
return moment().isBefore(end); // True
}
return false;
},
});
}
Forms.helpers({
isVisibleFields() {
/* if(this.isMe()){
return true;
}else{
if(this.isPublicFields(field)){
return true;
}else{
if(this.isFollowersMe() && this.isPrivateFields(field)){
return true;
}else{
return false;
}
}
} */
return true;
},
/* creatorProfile() {
return Citoyens.findOne({ _id: new Mongo.ObjectID(this.creator) });
}, */
isCreator() {
return this.creator === Meteor.userId();
},
scopeVar() {
return 'forms';
},
scopeEdit() {
return 'formsEdit';
},
listScope() {
return 'listForms';
},
creatorProfile() {
return Citoyens.findOne({ _id: new Mongo.ObjectID(this.creator) });
},
isAdmin(userId) {
const bothUserId = (typeof userId !== 'undefined') ? userId : Meteor.userId();
const citoyen = Citoyens.findOne({ _id: new Mongo.ObjectID(bothUserId) });
const organizerProject = this.organizerForm();
if (bothUserId && this.parent) {
return isAdminArray(organizerProject, citoyen);
}
},
organizerForm() {
if (this.parent) {
const childrenParent = arrayOrganizerParent(this.parent, ['organizations', 'projects']);
if (childrenParent) {
return childrenParent;
}
}
return undefined;
},
isStart() {
const start = moment(this.startDate, 'DD/MM/YYYY').toDate();
return moment(start).isBefore(); // True
},
formatStartDate() {
// todo : utilisé local
// return moment(this.startDate).format('DD/MM/YYYY HH:mm');
return moment(this.startDate, 'DD/MM/YYYY').format('L LT');
},
formatEndDate() {
// todo : utilisé local
// return moment(this.endDate).format('DD/MM/YYYY HH:mm');
return moment(this.endDate, 'DD/MM/YYYY').format('L LT');
},
formatStartDateIso() {
// todo : utilisé local
// return moment(this.startDate).format('DD/MM/YYYY HH:mm');
return moment(this.startDate, 'DD/MM/YYYY');
},
formatEndDateIso() {
// todo : utilisé local
// return moment(this.endDate).format('DD/MM/YYYY HH:mm');
return moment(this.endDate, 'DD/MM/YYYY');
},
duration() {
const a = moment(this.startDate, 'DD/MM/YYYY');
const b = moment(this.endDate, 'DD/MM/YYYY');
const diffInMs = b.diff(a); // 86400000 milliseconds
// const diffInDays = b.diff(a, 'days'); // 1 day
const diffInDayText = moment.duration(diffInMs).humanize();
return diffInDayText;
},
listAnswers(search, searchSort) {
let query = {};
query['answers.aapStep1'] = { $exists: true };
query.form = this._id._str;
if (Meteor.isClient) {
if (search) {
query = searchQueryAnswers(query, search);
}
}
const options = {};
if (Meteor.isClient) {
console.log('searchSort', searchSort);
if (searchSort) {
const arraySort = searchQuerySort('answers', searchSort);
if (arraySort) {
options.sort = arraySort;
}
}
} else {
options.sort = {
created: 1,
};
}
return Answers.find(query, options);
},
countAnswers(search) {
return this.listAnswers(search) && this.listAnswers(search).count();
},
});
......@@ -10,3 +10,5 @@ import './news.js';
import './comments.js';
import './loguseractions.js';
import './activitystream.js';
import './forms.js';
import './answers.js';
......@@ -18,6 +18,8 @@ import { Projects } from '../collection/projects.js';
import { Rooms } from '../collection/rooms.js';
import { Actions } from '../collection/actions.js';
import { ActivityStream } from '../collection/activitystream.js';
import { Forms } from '../collection/forms.js';
import {
searchQuery, searchQuerySort, queryLink, queryLinkParent, queryLinkType, queryLinkIsAdmin, arrayLinkParent, arrayLinkParentNoObject, arrayLinkToBeValidated, queryLinkToBeValidated, queryOptions, applyDiacritics, queryOrPrivatescopeIds,
} from '../helpers.js';
......@@ -197,6 +199,13 @@ Organizations.helpers({
// return this.links && this.links.projects && _.size(this.links.projects);
return this.listProjects(search) && this.listProjects(search).count();
},
listForms() {
const queryProjectId = `parent.${this._id._str}`;
return Forms.find({ [queryProjectId]: { $exists: true } });
},
countForms() {
return this.listForms() && this.listForms().count();
},
listRooms(search) {
if (Citoyens.findOne({ _id: new Mongo.ObjectID(Meteor.userId()) }).isScope(this.scopeVar(), this._id._str)) {
const query = {};
......
......@@ -15,6 +15,8 @@ import { Events } from '../collection/events.js';
import { Rooms } from '../collection/rooms.js';
import { Actions } from '../collection/actions.js';
import { ActivityStream } from '../collection/activitystream.js';
import { Forms } from '../collection/forms.js';
import {
searchQuery, searchQuerySort, queryLink, queryLinkType, arrayLinkParent, arrayOrganizerParent, isAdminArray, arrayLinkToBeValidated, queryLinkToBeValidated, queryOptions,
} from '../helpers.js';
......@@ -270,6 +272,13 @@ Projects.helpers({
// return this.links && this.links.events && _.size(this.links.events);
return this.listEventsCreator() && this.listEventsCreator().count();
},
listForms() {
const queryProjectId = `parent.${this._id._str}`;
return Forms.find({ [queryProjectId]: { $exists: true } });
},
countForms() {
return this.listForms() && this.listForms().count();
},
listProjectsCreator() {
if (this.links && this.links.projects) {
const projectIds = arrayLinkParent(this.links.projects, 'projects');
......
......@@ -219,6 +219,19 @@ export const searchQuery = (query, search) => {
return query;
};
export const searchQueryAnswers = (query, search) => {
if (search) {
if (search && search.charAt(0) === '#' && search.length > 1) {
const searchApplyDiacritics = applyDiacritics(search.substr(1).replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'regex');
query['answers.aapStep1.tags'] = { $regex: searchApplyDiacritics, $options: 'i' };
} else if (search && search.length > 1) {
const searchApplyDiacritics = applyDiacritics(search.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'regex');
query['answers.aapStep1.titre'] = { $regex: `.*${searchApplyDiacritics}.*`, $options: 'i' };
}
}
return query;
};
export const searchQuerySort = (type, sort) => {
if (sort && sort[type] && sort[type].length > 0) {
const arrayChecked = [...sort[type]].filter((item) => item.checked === true).sort(compareValues('order'));
......
......@@ -27,6 +27,9 @@ import { Resolutions } from '../collection/resolutions.js';
import { Rooms } from '../collection/rooms.js';
import { Proposals } from '../collection/proposals.js';
import { Forms } from '../collection/forms.js';
import { Answers } from '../collection/answers.js';
import {
nameToCollection, arrayLinkProperNoObject, arrayLinkParentNoObject, arrayChildrenParent, queryOrPrivateScope,
} from '../helpers.js';
......@@ -42,6 +45,8 @@ global.Actions = Actions;
global.Resolutions = Resolutions;
global.Rooms = Rooms;
global.Proposals = Proposals;
global.Forms = Forms;
global.Answers = Answers;
Events._ensureIndex({
geoPosition: '2dsphere',
......@@ -321,7 +326,7 @@ Meteor.publishComposite('scopeDetail', function (scope, scopeId) {
check(scopeId, String);
check(scope, String);
check(scope, Match.Where(function (name) {
return _.contains(['events', 'projects', 'organizations', 'citoyens', 'actions', 'rooms', 'proposals', 'resolutions'], name);
return _.contains(['events', 'projects', 'organizations', 'citoyens', 'actions', 'rooms', 'proposals', 'resolutions', 'forms'], name);
}));
const collection = nameToCollection(scope);
if (!this.userId) {
......@@ -872,6 +877,56 @@ Meteor.publishComposite('directoryListEvents', function (scope, scopeId) {
};
});
Meteor.publishComposite('directoryListForms', function (scope, scopeId) {
check(scopeId, String);
check(scope, String);
check(scope, Match.Where(function (name) {
return _.contains(['organizations', 'projects'], name);
}));
const collection = nameToCollection(scope);
if (!this.userId) {
return null;
}
return {
find() {
const options = {};
let query = {};
query.$or = [];
query.$or.push({
_id: new Mongo.ObjectID(scopeId),
'preferences.private': false,
});
query.$or.push({
_id: new Mongo.ObjectID(scopeId),
'preferences.private': {
$exists: false,
},
});
if (scope === 'projects') {
query = queryOrPrivateScope(query, 'contributors', scopeId, this.userId);
} else if (scope === 'organizations') {
query = queryOrPrivateScope(query, 'members', scopeId, this.userId);
}
return collection.find(query, options);
},
children: [
{
find() {
return Lists.find({ name: { $in: ['eventTypes'] } });
},
},
{
find(scopeD) {
if (scope === 'projects' || scope === 'organizations') {
return scopeD.listForms();
}
},
},
],
};
});
Meteor.publishComposite('directoryProjectsListEvents', function (scope, scopeId, startDateCal) {
check(scopeId, String);
check(scope, String);
......@@ -1380,6 +1435,61 @@ Meteor.publishComposite('directoryListActions', function (scope, scopeId, etat,
};
});
Meteor.publishComposite('directoryListAnswers', function (scope, scopeId) {
check(scopeId, String);
check(scope, String);
check(scope, Match.Where(function (name) {
return _.contains(['forms'], name);
}));
const collection = nameToCollection(scope);
if (!this.userId) {
return null;
}
return {
find() {
const options = {};
const query = {};
query._id = new Mongo.ObjectID(scopeId);