1 | var _ = require('@sailshq/lodash');
|
2 | var async = require('async');
|
3 | var moment = require('moment');
|
4 |
|
5 | module.exports = {
|
6 | name: 'apostrophe-event',
|
7 | alias: 'events',
|
8 | label: 'Event',
|
9 | extend: 'apostrophe-pieces',
|
10 |
|
11 | moogBundle: {
|
12 | modules: ['apostrophe-events-pages', 'apostrophe-events-widgets'],
|
13 | directory: 'lib/modules'
|
14 | },
|
15 |
|
16 | beforeConstruct: function(self, options) {
|
17 | options.sort = {
|
18 | startDate: 1,
|
19 | startTime: 1
|
20 | };
|
21 |
|
22 | options.addFields = [
|
23 | {
|
24 | name: 'startDate',
|
25 | label: 'Date',
|
26 | help: 'The date, or starting date, of the event',
|
27 | type: 'date',
|
28 | required: true
|
29 | },
|
30 | {
|
31 | name: 'allDay',
|
32 | label: 'Is this an all day event?',
|
33 | type: 'boolean',
|
34 | choices: [
|
35 | {
|
36 | label: 'Yes',
|
37 | value: true
|
38 | },
|
39 | {
|
40 | label: 'No',
|
41 | value: false,
|
42 | showFields: ['startTime', 'endTime']
|
43 | }
|
44 | ],
|
45 | def: false
|
46 | },
|
47 | {
|
48 | name: 'startTime',
|
49 | label: 'Start Time',
|
50 | type: 'time',
|
51 | def: '09:00:00',
|
52 | required: true
|
53 | },
|
54 | {
|
55 | name: 'endTime',
|
56 | label: 'End Time',
|
57 | type: 'time',
|
58 | def: '17:30:00',
|
59 | required: true
|
60 | },
|
61 | {
|
62 | name: 'dateType',
|
63 | label: 'What type of event is this?',
|
64 | help: 'Select if the event is on a single day, consecutive days, or repeats.',
|
65 | type: 'select',
|
66 | choices: [
|
67 | {
|
68 | label: 'Single Day',
|
69 | value: 'single'
|
70 | },
|
71 | {
|
72 | label: 'Consecutive Days',
|
73 | value: 'consecutive',
|
74 | showFields: ['endDate']
|
75 | },
|
76 | {
|
77 | label: 'Recurring',
|
78 | value: 'repeat',
|
79 | showFields: ['repeatInterval', 'repeatCount']
|
80 | }
|
81 | ],
|
82 | def: 'single'
|
83 | },
|
84 | {
|
85 | name: 'endDate',
|
86 | label: 'End Date',
|
87 | type: 'date'
|
88 | },
|
89 | {
|
90 | name: 'repeatInterval',
|
91 | label: 'How often does the event repeat?',
|
92 | type: 'select',
|
93 | choices: [
|
94 | {
|
95 | label: 'Every week',
|
96 | value: 'weeks'
|
97 | },
|
98 | {
|
99 | label: 'Every month',
|
100 | value: 'months'
|
101 | }
|
102 | ]
|
103 | },
|
104 | {
|
105 | name: 'repeatCount',
|
106 | label: 'How many times does it repeat?',
|
107 | type: 'integer',
|
108 | def: 1
|
109 | }
|
110 | ].concat(options.addFields || []);
|
111 |
|
112 | options.arrangeFields = options.arrangeFields || [
|
113 | {
|
114 | name: 'basic',
|
115 | label: 'Basics',
|
116 | fields: ['title', 'slug', 'startDate', 'allDay', 'startTime', 'endTime']
|
117 | },
|
118 | {
|
119 | name: 'advanced',
|
120 | label: 'Advanced',
|
121 | fields: ['dateType', 'endDate', 'repeatInterval', 'repeatCount']
|
122 | },
|
123 | {
|
124 | name: 'meta',
|
125 | label: 'Meta',
|
126 | fields: ['tags', 'published']
|
127 | }
|
128 | ];
|
129 |
|
130 | options.addColumns = [
|
131 | {
|
132 | name: 'startDate',
|
133 | label: 'Start Date'
|
134 | }
|
135 | ].concat(options.addColumns || []);
|
136 |
|
137 | options.addSorts = [
|
138 | {
|
139 | name: 'startDate',
|
140 | label: 'By Start Date',
|
141 | sort: { startDate: -1 }
|
142 | }
|
143 | ].concat(options.addSorts || []);
|
144 |
|
145 | options.addFilters = [
|
146 | {
|
147 | name: 'upcoming',
|
148 | choices: [
|
149 | {
|
150 | value: true,
|
151 | label: 'Upcoming'
|
152 | },
|
153 | {
|
154 | value: false,
|
155 | label: 'Past'
|
156 | },
|
157 | {
|
158 | value: null,
|
159 | label: 'Both'
|
160 | }
|
161 | ],
|
162 | def: true
|
163 | }
|
164 | ].concat(options.addFilters || []);
|
165 | },
|
166 |
|
167 | construct: function(self, options) {
|
168 |
|
169 |
|
170 |
|
171 | self.extendAutocompleteCursor = function(cursor) {
|
172 | return cursor.upcoming(true);
|
173 | };
|
174 |
|
175 | self.beforeSave = function(req, piece, options, callback) {
|
176 | self.denormalizeDatesAndTimes(piece);
|
177 | return callback(null);
|
178 | };
|
179 |
|
180 | self.afterSave = function(req, piece, options, callback) {
|
181 | if (piece._workflowPropagating) {
|
182 |
|
183 |
|
184 | return callback(null);
|
185 | }
|
186 |
|
187 | if (piece.dateType !== 'repeat') {
|
188 | return callback(null);
|
189 | }
|
190 |
|
191 | self
|
192 | .find(req, { parentId: piece._id, trash: false }, { _id: 1 })
|
193 | .toArray(function(err, docs) {
|
194 | if (err) {
|
195 | return callback(err);
|
196 | }
|
197 | if (!docs.length) {
|
198 |
|
199 | return self.repeatEvent(req, piece, callback);
|
200 | }
|
201 | callback(null);
|
202 | });
|
203 | };
|
204 |
|
205 | self.denormalizeDatesAndTimes = function(piece) {
|
206 |
|
207 | var startTime = piece.startTime;
|
208 | var startDate = piece.startDate;
|
209 | var endTime = piece.endTime;
|
210 | var endDate;
|
211 |
|
212 | if (piece.dateType === 'consecutive') {
|
213 | endDate = piece.endDate;
|
214 | } else {
|
215 | piece.endDate = piece.startDate;
|
216 | endDate = piece.startDate;
|
217 | }
|
218 |
|
219 | if (piece.allDay) {
|
220 | startTime = '00:00:00';
|
221 | endTime = '23:59:59';
|
222 | }
|
223 |
|
224 | if (piece.dateType === 'repeat') {
|
225 | piece.hasClones = true;
|
226 | }
|
227 |
|
228 | piece.start = new Date(startDate + ' ' + startTime);
|
229 | piece.end = new Date(endDate + ' ' + endTime);
|
230 | };
|
231 |
|
232 | self.repeatEvent = function(req, piece, finalCallback) {
|
233 | var i;
|
234 | var repeat = parseInt(piece.repeatCount) + 1;
|
235 | var multiplier = piece.repeatInterval;
|
236 | var addDates = [];
|
237 |
|
238 | for (i = 1; i < repeat; i++) {
|
239 | addDates.push(moment(piece.startDate).add(i, multiplier).format('YYYY-MM-DD'));
|
240 | }
|
241 |
|
242 | return async.eachLimit(addDates, 5, function(date, callback) {
|
243 | var eventCopy = _.cloneDeep(piece);
|
244 | eventCopy._id = self.apos.utils.generateId();
|
245 | if (piece.workflowGuid) {
|
246 | eventCopy.workflowGuid = self.apos.utils.generateId();
|
247 | }
|
248 | eventCopy.parentId = piece._id;
|
249 | eventCopy.isClone = true;
|
250 | eventCopy.startDate = date;
|
251 | eventCopy.endDate = date;
|
252 | eventCopy.slug = eventCopy.slug + '-' + date;
|
253 | eventCopy.dateType = 'single';
|
254 | self.denormalizeDatesAndTimes(eventCopy);
|
255 | return self.insert(req, eventCopy, callback);
|
256 | }, finalCallback);
|
257 | };
|
258 | }
|
259 | };
|