@plusscommunities/pluss-maintenance-web-forms 1.1.37-beta.4 → 1.1.37-beta.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/index.cjs.js +547 -573
  2. package/dist/index.esm.js +549 -575
  3. package/dist/index.js +6724 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/index.umd.js +548 -574
  6. package/package.json +6 -2
  7. package/.babelrc +0 -3
  8. package/rollup.config.js +0 -59
  9. package/src/actions/JobsActions.js +0 -150
  10. package/src/actions/index.js +0 -1
  11. package/src/actions/types.js +0 -8
  12. package/src/apis/index.js +0 -10
  13. package/src/apis/maintenanceActions.js +0 -203
  14. package/src/apis/reactionActions.js +0 -46
  15. package/src/components/ActivityText.js +0 -57
  16. package/src/components/AnalyticsHub.js +0 -364
  17. package/src/components/Configuration.js +0 -392
  18. package/src/components/JobList.js +0 -1108
  19. package/src/components/JobTypes.js +0 -198
  20. package/src/components/PreviewFull.js +0 -33
  21. package/src/components/PreviewGrid.js +0 -29
  22. package/src/components/PreviewWidget.js +0 -35
  23. package/src/components/ViewFull.js +0 -25
  24. package/src/components/ViewWidget.js +0 -23
  25. package/src/feature.config.js +0 -127
  26. package/src/helper/index.js +0 -26
  27. package/src/images/forms/full.png +0 -0
  28. package/src/images/forms/fullNoTitle.png +0 -0
  29. package/src/images/forms/previewWidget.png +0 -0
  30. package/src/images/forms/widget.png +0 -0
  31. package/src/images/full.png +0 -0
  32. package/src/images/fullNoTitle.png +0 -0
  33. package/src/images/previewWidget.png +0 -0
  34. package/src/images/widget.png +0 -0
  35. package/src/index.js +0 -29
  36. package/src/maintenancePriority.json +0 -5
  37. package/src/maintenanceStatus.json +0 -20
  38. package/src/reducers/MaintenanceReducer.js +0 -49
  39. package/src/screens/AddJob.js +0 -1138
  40. package/src/screens/AddJobType.js +0 -865
  41. package/src/screens/Job.js +0 -1531
  42. package/src/screens/RequestsHub.js +0 -237
  43. package/src/values.config.a.js +0 -63
  44. package/src/values.config.default.js +0 -75
  45. package/src/values.config.enquiry.js +0 -76
  46. package/src/values.config.feedback.js +0 -74
  47. package/src/values.config.food.js +0 -74
  48. package/src/values.config.forms.js +0 -74
  49. package/src/values.config.js +0 -74
package/dist/index.cjs.js CHANGED
@@ -6,12 +6,12 @@ var _defineProperty = require('@babel/runtime/helpers/defineProperty');
6
6
  var React = require('react');
7
7
  var reactRedux = require('react-redux');
8
8
  var reactRouter = require('react-router');
9
- var _ = require('lodash');
10
- var moment = require('moment');
11
- var FontAwesome = require('react-fontawesome');
12
9
  var PlussCore = require('@plusscommunities/pluss-core-web');
13
10
  var reactBootstrap = require('react-bootstrap');
14
11
  var reactRouterDom = require('react-router-dom');
12
+ var FontAwesome = require('react-fontawesome');
13
+ var moment = require('moment');
14
+ var _ = require('lodash');
15
15
  var Textarea = require('react-textarea-autosize');
16
16
  var freeSolidSvgIcons = require('@fortawesome/free-solid-svg-icons');
17
17
 
@@ -37,10 +37,10 @@ function _interopNamespace(e) {
37
37
 
38
38
  var _defineProperty__default = /*#__PURE__*/_interopDefaultLegacy(_defineProperty);
39
39
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
40
- var ___default = /*#__PURE__*/_interopDefaultLegacy(_);
41
- var moment__default = /*#__PURE__*/_interopDefaultLegacy(moment);
42
- var FontAwesome__default = /*#__PURE__*/_interopDefaultLegacy(FontAwesome);
43
40
  var PlussCore__namespace = /*#__PURE__*/_interopNamespace(PlussCore);
41
+ var FontAwesome__default = /*#__PURE__*/_interopDefaultLegacy(FontAwesome);
42
+ var moment__default = /*#__PURE__*/_interopDefaultLegacy(moment);
43
+ var ___default = /*#__PURE__*/_interopDefaultLegacy(_);
44
44
  var Textarea__default = /*#__PURE__*/_interopDefaultLegacy(Textarea);
45
45
 
46
46
  const values = {
@@ -112,7 +112,13 @@ const values = {
112
112
  hasHelpButton: true,
113
113
  helpGuideURL: 'https://www.plusscommunities.com/forms-feature',
114
114
  stringConfigJobStatus: 'maintenanceJobStatusForms',
115
- stringConfigHideSeen: 'maintenanceDisableSeenForms'
115
+ stringConfigHideSeen: 'maintenanceDisableSeenForms',
116
+ // Comment subscription notification preference
117
+ notificationPreference: {
118
+ key: 'maintenancerequestFormsComments',
119
+ label: 'Forms comments',
120
+ permission: 'maintenanceTrackingForms'
121
+ }
116
122
  };
117
123
 
118
124
  // import * as PlussCore from '../../pluss-core/src';
@@ -235,7 +241,8 @@ const FeatureConfig = {
235
241
  init: environment => {
236
242
  FeatureConfig.env = environment;
237
243
  PlussCore__namespace.Config.init(environment);
238
- }
244
+ },
245
+ notificationPreference: values.notificationPreference
239
246
  };
240
247
 
241
248
  const JOBS_LOADED = values.actionJobsLoaded;
@@ -245,15 +252,15 @@ const JOBS_TYPES_LOADED = values.actionJobsTypesLoaded;
245
252
  const JOBS_STATUSES_LOADED = values.actionJobsStatusesLoaded;
246
253
  const JOBS_HIDE_SEEN = values.actionJobsHideSeen;
247
254
 
248
- function ownKeys$8(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
249
- function _objectSpread$8(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$8(Object(t), !0).forEach(function (r) { _defineProperty__default["default"](e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$8(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
255
+ function ownKeys$7(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
256
+ function _objectSpread$7(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$7(Object(t), !0).forEach(function (r) { _defineProperty__default["default"](e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$7(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
250
257
  const {
251
- Helper: Helper$6,
258
+ Helper: Helper$4,
252
259
  Session: Session$9
253
260
  } = PlussCore__namespace;
254
- const maintenanceActions = {
261
+ const maintenanceActions$1 = {
255
262
  getJobType: (site, typeId) => {
256
- let url = Helper$6.getUrl(values.serviceKey, 'getjobtype');
263
+ let url = Helper$4.getUrl(values.serviceKey, 'getjobtype');
257
264
  return Session$9.authedFunction({
258
265
  method: 'POST',
259
266
  url,
@@ -264,7 +271,7 @@ const maintenanceActions = {
264
271
  });
265
272
  },
266
273
  getJobTypes: (site, id) => {
267
- let url = Helper$6.getUrl(values.serviceKey, 'getjobtypes');
274
+ let url = Helper$4.getUrl(values.serviceKey, 'getjobtypes');
268
275
  return Session$9.authedFunction({
269
276
  method: 'POST',
270
277
  url,
@@ -274,7 +281,7 @@ const maintenanceActions = {
274
281
  });
275
282
  },
276
283
  getJob: (site, id) => {
277
- let url = Helper$6.getUrl(values.serviceKey, 'getJob');
284
+ let url = Helper$4.getUrl(values.serviceKey, 'getJob');
278
285
  return Session$9.authedFunction({
279
286
  method: 'POST',
280
287
  url,
@@ -285,7 +292,7 @@ const maintenanceActions = {
285
292
  });
286
293
  },
287
294
  getJobByJobId: (site, jobId) => {
288
- let url = Helper$6.getUrl(values.serviceKey, 'getJob');
295
+ let url = Helper$4.getUrl(values.serviceKey, 'getJob');
289
296
  return Session$9.authedFunction({
290
297
  method: 'POST',
291
298
  url,
@@ -300,7 +307,7 @@ const maintenanceActions = {
300
307
  let type = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
301
308
  return Session$9.authedFunction({
302
309
  method: 'POST',
303
- url: Helper$6.getUrl(values.serviceKey, 'getJobs'),
310
+ url: Helper$4.getUrl(values.serviceKey, 'getJobs'),
304
311
  data: {
305
312
  site,
306
313
  status,
@@ -308,7 +315,7 @@ const maintenanceActions = {
308
315
  }
309
316
  });
310
317
  },
311
- getJobs2: (site, status, type, lastKey) => {
318
+ getJobs2: (site, status, type, priority, assignee, startTime, endTime, search, lastKey) => {
312
319
  const query = {
313
320
  site
314
321
  };
@@ -318,37 +325,57 @@ const maintenanceActions = {
318
325
  if (type) {
319
326
  query.type = type;
320
327
  }
328
+ if (priority) {
329
+ query.priority = priority;
330
+ }
331
+ if (assignee) {
332
+ query.assignee = assignee;
333
+ }
334
+ if (startTime) {
335
+ query.startTime = startTime;
336
+ }
337
+ if (endTime) {
338
+ query.endTime = endTime;
339
+ }
340
+ if (search) {
341
+ query.search = search;
342
+ }
321
343
  if (lastKey) {
322
344
  query.lastKey = JSON.stringify(lastKey);
323
345
  }
324
346
  return Session$9.authedFunction({
325
347
  method: 'GET',
326
- url: Helper$6.getUrl(values.serviceKey, 'get/requests', query)
348
+ url: Helper$4.getUrl(values.serviceKey, 'get/requests', query)
327
349
  });
328
350
  },
351
+ /**
352
+ * @deprecated Use getJobs2 with pagination instead.
353
+ * This method recursively fetches ALL pages which can be slow for large datasets.
354
+ * Only use for CSV export where all data is needed.
355
+ */
329
356
  getJobsRecursive: function (site, status, type, lastKey) {
330
357
  let jobs = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : [];
331
- return new Promise(resolve => {
332
- maintenanceActions.getJobs2(site, status, type, lastKey).then(jobRes => {
358
+ return new Promise((resolve, reject) => {
359
+ maintenanceActions$1.getJobs2(site, status, type, undefined, undefined, undefined, undefined, undefined, lastKey).then(jobRes => {
333
360
  const newJobs = [...jobs, ...jobRes.data.Items];
334
361
  if (!jobRes.data.LastKey) {
335
362
  return resolve(newJobs);
336
363
  }
337
- return resolve(maintenanceActions.getJobsRecursive(site, status, type, jobRes.data.LastKey, newJobs));
338
- });
364
+ maintenanceActions$1.getJobsRecursive(site, status, type, jobRes.data.LastKey, newJobs).then(resolve).catch(reject);
365
+ }).catch(reject);
339
366
  });
340
367
  },
341
368
  createJob: job => {
342
369
  return Session$9.authedFunction({
343
370
  method: 'POST',
344
- url: Helper$6.getUrl(values.serviceKey, 'sendMaintenance'),
345
- data: _objectSpread$8({}, job)
371
+ url: Helper$4.getUrl(values.serviceKey, 'sendMaintenance'),
372
+ data: _objectSpread$7({}, job)
346
373
  });
347
374
  },
348
375
  editJob: (job, site) => {
349
376
  return Session$9.authedFunction({
350
377
  method: 'POST',
351
- url: Helper$6.getUrl(values.serviceKey, 'editJob'),
378
+ url: Helper$4.getUrl(values.serviceKey, 'editJob'),
352
379
  data: {
353
380
  job,
354
381
  site
@@ -358,7 +385,7 @@ const maintenanceActions = {
358
385
  deleteJob: (site, id) => {
359
386
  return Session$9.authedFunction({
360
387
  method: 'POST',
361
- url: Helper$6.getUrl(values.serviceKey, 'requests/remove'),
388
+ url: Helper$4.getUrl(values.serviceKey, 'requests/remove'),
362
389
  data: {
363
390
  site,
364
391
  id
@@ -368,7 +395,7 @@ const maintenanceActions = {
368
395
  editJobStatus: (id, status) => {
369
396
  return Session$9.authedFunction({
370
397
  method: 'POST',
371
- url: Helper$6.getUrl(values.serviceKey, 'editJobStatus'),
398
+ url: Helper$4.getUrl(values.serviceKey, 'editJobStatus'),
372
399
  data: {
373
400
  id,
374
401
  status
@@ -378,7 +405,7 @@ const maintenanceActions = {
378
405
  editJobPriority: (id, priority) => {
379
406
  return Session$9.authedFunction({
380
407
  method: 'POST',
381
- url: Helper$6.getUrl(values.serviceKey, 'update/priority'),
408
+ url: Helper$4.getUrl(values.serviceKey, 'update/priority'),
382
409
  data: {
383
410
  id,
384
411
  priority
@@ -388,7 +415,7 @@ const maintenanceActions = {
388
415
  assignJob: (jobId, userId) => {
389
416
  return Session$9.authedFunction({
390
417
  method: 'POST',
391
- url: Helper$6.getUrl(values.serviceKey, 'update/assign'),
418
+ url: Helper$4.getUrl(values.serviceKey, 'update/assign'),
392
419
  data: {
393
420
  id: jobId,
394
421
  userId
@@ -398,7 +425,7 @@ const maintenanceActions = {
398
425
  getAssignees: site => {
399
426
  return Session$9.authedFunction({
400
427
  method: 'GET',
401
- url: Helper$6.getUrl(values.serviceKey, 'get/assignees', {
428
+ url: Helper$4.getUrl(values.serviceKey, 'get/assignees', {
402
429
  site
403
430
  })
404
431
  });
@@ -406,7 +433,7 @@ const maintenanceActions = {
406
433
  addNote: (jobId, note, attachments, images) => {
407
434
  return Session$9.authedFunction({
408
435
  method: 'POST',
409
- url: Helper$6.getUrl(values.serviceKey, 'requests/note'),
436
+ url: Helper$4.getUrl(values.serviceKey, 'requests/note'),
410
437
  data: {
411
438
  id: jobId,
412
439
  note,
@@ -419,7 +446,7 @@ const maintenanceActions = {
419
446
  editNote: (jobId, noteId, note, attachments, images) => {
420
447
  return Session$9.authedFunction({
421
448
  method: 'POST',
422
- url: Helper$6.getUrl(values.serviceKey, 'requests/note'),
449
+ url: Helper$4.getUrl(values.serviceKey, 'requests/note'),
423
450
  data: {
424
451
  id: jobId,
425
452
  note,
@@ -433,7 +460,7 @@ const maintenanceActions = {
433
460
  deleteNote: (jobId, noteId) => {
434
461
  return Session$9.authedFunction({
435
462
  method: 'POST',
436
- url: Helper$6.getUrl(values.serviceKey, 'requests/note'),
463
+ url: Helper$4.getUrl(values.serviceKey, 'requests/note'),
437
464
  data: {
438
465
  id: jobId,
439
466
  noteId,
@@ -453,7 +480,7 @@ const maintenanceActions = {
453
480
  };
454
481
  return Session$9.authedFunction({
455
482
  method: 'POST',
456
- url: Helper$6.getUrl(values.serviceKey, 'createJobType'),
483
+ url: Helper$4.getUrl(values.serviceKey, 'createJobType'),
457
484
  data
458
485
  });
459
486
  },
@@ -471,14 +498,14 @@ const maintenanceActions = {
471
498
  if (hasCustomFields && customFields) data.customFields = customFields;
472
499
  return Session$9.authedFunction({
473
500
  method: 'POST',
474
- url: Helper$6.getUrl(values.serviceKey, 'editJobType'),
501
+ url: Helper$4.getUrl(values.serviceKey, 'editJobType'),
475
502
  data
476
503
  });
477
504
  },
478
505
  deleteJobType: (site, id) => {
479
506
  return Session$9.authedFunction({
480
507
  method: 'POST',
481
- url: Helper$6.getUrl(values.serviceKey, 'deleteJobType'),
508
+ url: Helper$4.getUrl(values.serviceKey, 'deleteJobType'),
482
509
  data: {
483
510
  site,
484
511
  id
@@ -488,7 +515,7 @@ const maintenanceActions = {
488
515
  getExternalSync: jobId => {
489
516
  return Session$9.authedFunction({
490
517
  method: 'GET',
491
- url: Helper$6.getUrl(values.serviceKey, 'get/externalsync', {
518
+ url: Helper$4.getUrl(values.serviceKey, 'get/externalsync', {
492
519
  id: jobId
493
520
  })
494
521
  });
@@ -496,7 +523,7 @@ const maintenanceActions = {
496
523
  retrySync: jobId => {
497
524
  return Session$9.authedFunction({
498
525
  method: 'POST',
499
- url: Helper$6.getUrl(values.serviceKey, 'update/retrysync'),
526
+ url: Helper$4.getUrl(values.serviceKey, 'update/retrysync'),
500
527
  data: {
501
528
  id: jobId
502
529
  }
@@ -505,7 +532,7 @@ const maintenanceActions = {
505
532
  };
506
533
 
507
534
  const {
508
- Helper: Helper$5,
535
+ Helper: Helper$3,
509
536
  Session: Session$8
510
537
  } = PlussCore__namespace;
511
538
  const reactionActions = {
@@ -523,7 +550,7 @@ const reactionActions = {
523
550
  }
524
551
  return Session$8.authedFunction({
525
552
  method: 'POST',
526
- url: Helper$5.getUrl('reactions', 'comments/add'),
553
+ url: Helper$3.getUrl('reactions', 'comments/add'),
527
554
  data
528
555
  });
529
556
  },
@@ -546,7 +573,7 @@ const reactionActions = {
546
573
  }
547
574
  return Session$8.authedFunction({
548
575
  method: 'GET',
549
- url: Helper$5.getUrl('reactions', 'comments/get', query)
576
+ url: Helper$3.getUrl('reactions', 'comments/get', query)
550
577
  });
551
578
  }
552
579
  };
@@ -579,30 +606,6 @@ var jobStatusOptions = [
579
606
  }
580
607
  ];
581
608
 
582
- const {
583
- Helper: Helper$4
584
- } = PlussCore__namespace;
585
- const jobsUpdate = (site, isdashboard) => {
586
- return dispatch => {
587
- if (isdashboard) dispatch({
588
- type: JOBS_LOADING
589
- });
590
- maintenanceActions.getJobsRecursive(site).then(res => {
591
- const currentSite = Helper$4.readStorageWithCookie('site');
592
- if (!___default["default"].isEmpty(res) && res[0].site === currentSite) {
593
- dispatch({
594
- type: JOBS_LOADED,
595
- payload: res
596
- });
597
- } else {
598
- dispatch({
599
- type: JOBS_LOADED,
600
- payload: []
601
- });
602
- }
603
- });
604
- };
605
- };
606
609
  const jobsLoaded = events => {
607
610
  return {
608
611
  type: JOBS_LOADED,
@@ -740,8 +743,8 @@ const getJobPriority = priority => {
740
743
  return priorityOption || getDefaultPriority();
741
744
  };
742
745
 
743
- function ownKeys$7(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
744
- function _objectSpread$7(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$7(Object(t), !0).forEach(function (r) { _defineProperty__default["default"](e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$7(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
746
+ function ownKeys$6(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
747
+ function _objectSpread$6(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$6(Object(t), !0).forEach(function (r) { _defineProperty__default["default"](e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$6(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
745
748
  const {
746
749
  Session: Session$7,
747
750
  Components: Components$7,
@@ -749,7 +752,155 @@ const {
749
752
  } = PlussCore__namespace;
750
753
  class JobList extends React.Component {
751
754
  constructor(props) {
755
+ var _this;
752
756
  super(props);
757
+ _this = this;
758
+ _defineProperty__default["default"](this, "getAssignees", async () => {
759
+ try {
760
+ const res = await maintenanceActions$1.getAssignees(this.props.auth.site);
761
+ this.setState({
762
+ assignees: res.data.Users
763
+ });
764
+ } catch (error) {
765
+ console.error('getAssignees', error);
766
+ }
767
+ });
768
+ /**
769
+ * Build server-side filter params from current filter state.
770
+ * Translates UI filter selections into API query parameters.
771
+ */
772
+ _defineProperty__default["default"](this, "buildFilterParams", () => {
773
+ const {
774
+ selectedStatusFilter,
775
+ selectedTypeFilter,
776
+ selectedPriorityFilter,
777
+ selectedUserFilter,
778
+ selectedTimeFilterStart,
779
+ selectedTimeFilterEnd,
780
+ searchTerm
781
+ } = this.state;
782
+ const {
783
+ statusTypes
784
+ } = this.props;
785
+ const params = {};
786
+
787
+ // Status filter: translate "All Incomplete" into the actual incomplete statuses
788
+ if (selectedStatusFilter) {
789
+ if (selectedStatusFilter === STATUS_IMCOMPLETE) {
790
+ // Exclude completed statuses - pass all non-completed status texts
791
+ const incompleteStatuses = statusTypes.filter(s => s.category !== STATUS_COMPLETED).map(s => s.text);
792
+ if (incompleteStatuses.length > 0) {
793
+ params.status = incompleteStatuses.join(',');
794
+ }
795
+ } else {
796
+ params.status = selectedStatusFilter;
797
+ }
798
+ }
799
+ if (selectedTypeFilter) {
800
+ params.type = selectedTypeFilter;
801
+ }
802
+ if (selectedPriorityFilter) {
803
+ params.priority = selectedPriorityFilter;
804
+ }
805
+ if (selectedUserFilter) {
806
+ params.assignee = selectedUserFilter;
807
+ }
808
+ if (selectedTimeFilterStart) {
809
+ params.startTime = selectedTimeFilterStart;
810
+ }
811
+ if (selectedTimeFilterEnd) {
812
+ params.endTime = selectedTimeFilterEnd;
813
+ }
814
+ if (searchTerm) {
815
+ params.search = searchTerm;
816
+ }
817
+ return params;
818
+ });
819
+ /**
820
+ * Monotonically increasing ID used to ignore stale fetch results.
821
+ * When a filter changes, fetchJobs() increments this counter. Any
822
+ * in-flight fetch checks the counter before applying results —
823
+ * if it doesn't match, the results are discarded.
824
+ */
825
+ _defineProperty__default["default"](this, "_fetchId", 0);
826
+ /**
827
+ * Fetch a single page from the server using the given lastKey.
828
+ */
829
+ _defineProperty__default["default"](this, "fetchPage", async function () {
830
+ let lastKey = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
831
+ const {
832
+ auth
833
+ } = _this.props;
834
+ const filters = _this.buildFilterParams();
835
+ return maintenanceActions$1.getJobs2(auth.site, filters.status, filters.type, filters.priority, filters.assignee, filters.startTime, filters.endTime, filters.search, lastKey);
836
+ });
837
+ /**
838
+ * Fetch the first page and render immediately.
839
+ */
840
+ _defineProperty__default["default"](this, "fetchJobs", async () => {
841
+ const fetchId = ++this._fetchId;
842
+ this.setState({
843
+ loading: true,
844
+ loadingMore: false
845
+ }, async () => {
846
+ try {
847
+ const res = await this.fetchPage(null);
848
+ if (this._fetchId !== fetchId) return;
849
+ const items = res.data.Items || [];
850
+ const lastKey = res.data.LastKey || null;
851
+ this.setState({
852
+ jobs: items,
853
+ lastKey,
854
+ hasMore: !!lastKey,
855
+ loading: false
856
+ });
857
+ this.props.jobsLoaded(items);
858
+ this.setRequesters(items);
859
+ } catch (error) {
860
+ if (this._fetchId !== fetchId) return;
861
+ console.error('fetchJobs', error);
862
+ this.setState({
863
+ loading: false
864
+ });
865
+ }
866
+ });
867
+ });
868
+ /**
869
+ * Load the next batch of jobs when the user clicks "Load More".
870
+ */
871
+ _defineProperty__default["default"](this, "loadMore", async () => {
872
+ const fetchId = ++this._fetchId;
873
+ const {
874
+ lastKey,
875
+ jobs
876
+ } = this.state;
877
+ this.setState({
878
+ loadingMore: true
879
+ }, async () => {
880
+ try {
881
+ const res = await this.fetchPage(lastKey);
882
+ if (this._fetchId !== fetchId) return;
883
+ const items = res.data.Items || [];
884
+ const newLastKey = res.data.LastKey || null;
885
+ const updatedJobs = [...jobs, ...items];
886
+ this.setState({
887
+ jobs: updatedJobs,
888
+ lastKey: newLastKey,
889
+ hasMore: !!newLastKey,
890
+ loadingMore: false
891
+ });
892
+ if (items.length > 0) {
893
+ this.props.jobsLoaded(items);
894
+ }
895
+ } catch (error) {
896
+ if (this._fetchId !== fetchId) return;
897
+ console.error('loadMore', error);
898
+ this.setState({
899
+ loadingMore: false
900
+ });
901
+ }
902
+ });
903
+ });
753
904
  _defineProperty__default["default"](this, "setRequesters", jobs => {
754
905
  const requesters = ___default["default"].orderBy(___default["default"].uniqBy(jobs.map(j => ({
755
906
  id: j.userID,
@@ -760,30 +911,6 @@ class JobList extends React.Component {
760
911
  requesters
761
912
  });
762
913
  });
763
- _defineProperty__default["default"](this, "getJobs", async () => {
764
- const {
765
- auth
766
- } = this.props;
767
- try {
768
- const res = await maintenanceActions.getJobsRecursive(auth.site);
769
- if (!___default["default"].isEmpty(res) && res[0].site === auth.site) {
770
- this.setRequesters(res);
771
- this.props.jobsLoaded(res);
772
- }
773
- } catch (error) {
774
- console.error('getJobs', error);
775
- }
776
- });
777
- _defineProperty__default["default"](this, "getAssignees", async () => {
778
- try {
779
- const res = await maintenanceActions.getAssignees(this.props.auth.site);
780
- this.setState({
781
- assignees: res.data.Users
782
- });
783
- } catch (error) {
784
- console.error('getAssignees', error);
785
- }
786
- });
787
914
  _defineProperty__default["default"](this, "sortByCol", col => {
788
915
  const {
789
916
  sortColumn,
@@ -803,9 +930,12 @@ class JobList extends React.Component {
803
930
  _defineProperty__default["default"](this, "onRemoveRequest", async request => {
804
931
  if (window.confirm(values.textAreYouSureYouWantToDelete)) {
805
932
  this.props.removeJob(request.id);
933
+ // Remove from local state immediately
934
+ this.setState(prevState => ({
935
+ jobs: prevState.jobs.filter(j => j.id !== request.id)
936
+ }));
806
937
  try {
807
- await maintenanceActions.deleteJob(this.props.auth.site, request.id);
808
- this.getJobs();
938
+ await maintenanceActions$1.deleteJob(this.props.auth.site, request.id);
809
939
  } catch (error) {
810
940
  console.log('onRemoveRequest', error);
811
941
  alert('Something went wrong with the request. Please try again.');
@@ -824,20 +954,20 @@ class JobList extends React.Component {
824
954
  });
825
955
  _defineProperty__default["default"](this, "selectTypeFilter", filter => {
826
956
  this.setState({
827
- selectedTypeFilter: filter
828
- });
957
+ selectedTypeFilter: filter || null
958
+ }, () => this.fetchJobs());
829
959
  this.closeFilter();
830
960
  });
831
961
  _defineProperty__default["default"](this, "selectPriorityFilter", filter => {
832
962
  this.setState({
833
- selectedPriorityFilter: filter
834
- });
963
+ selectedPriorityFilter: filter || null
964
+ }, () => this.fetchJobs());
835
965
  this.closeFilter();
836
966
  });
837
967
  _defineProperty__default["default"](this, "selectStatusFilter", filter => {
838
968
  this.setState({
839
- selectedStatusFilter: filter
840
- });
969
+ selectedStatusFilter: filter || null
970
+ }, () => this.fetchJobs());
841
971
  this.closeFilter();
842
972
  });
843
973
  _defineProperty__default["default"](this, "timeFilterChanged", selectedTimeFilter => {
@@ -881,7 +1011,7 @@ class JobList extends React.Component {
881
1011
  selectedTimeFilterStart: startTime,
882
1012
  selectedTimeFilterEnd: endTime,
883
1013
  selectedTimeFilterText: text
884
- });
1014
+ }, () => this.fetchJobs());
885
1015
  this.closeFilter();
886
1016
  });
887
1017
  _defineProperty__default["default"](this, "removeTimeFilter", () => {
@@ -889,7 +1019,7 @@ class JobList extends React.Component {
889
1019
  selectedTimeFilterStart: null,
890
1020
  selectedTimeFilterEnd: null,
891
1021
  selectedTimeFilterText: null
892
- });
1022
+ }, () => this.fetchJobs());
893
1023
  });
894
1024
  _defineProperty__default["default"](this, "onHandleChange", event => {
895
1025
  var stateChange = {};
@@ -905,7 +1035,7 @@ class JobList extends React.Component {
905
1035
  this.setState({
906
1036
  selectedUserFilter: null,
907
1037
  selectedUserFilterText: null
908
- });
1038
+ }, () => this.fetchJobs());
909
1039
  });
910
1040
  _defineProperty__default["default"](this, "saveUserFilter", () => {
911
1041
  if (!this.state.selectedAssignee) {
@@ -915,7 +1045,7 @@ class JobList extends React.Component {
915
1045
  selectedUserFilter: this.state.selectedAssignee.id,
916
1046
  selectedUserFilterText: this.state.selectedAssignee.displayName,
917
1047
  selectedAssignee: null
918
- });
1048
+ }, () => this.fetchJobs());
919
1049
  }
920
1050
  this.closeFilter();
921
1051
  });
@@ -928,7 +1058,7 @@ class JobList extends React.Component {
928
1058
  this.setState({
929
1059
  selectedRequesterFilter: null,
930
1060
  selectedRequesterFilterText: null
931
- });
1061
+ }, () => this.fetchJobs());
932
1062
  });
933
1063
  _defineProperty__default["default"](this, "saveRequesterFilter", () => {
934
1064
  if (!this.state.selectedRequester) {
@@ -938,7 +1068,7 @@ class JobList extends React.Component {
938
1068
  selectedRequesterFilter: this.state.selectedRequester.id,
939
1069
  selectedRequesterFilterText: this.state.selectedRequester.displayName,
940
1070
  selectedRequester: null
941
- });
1071
+ }, () => this.fetchJobs());
942
1072
  }
943
1073
  this.closeFilter();
944
1074
  });
@@ -949,85 +1079,47 @@ class JobList extends React.Component {
949
1079
  lastSearch: thisSearchTime
950
1080
  });
951
1081
  setTimeout(() => {
952
- // delayed setter to avoid filtering on every keypress
1082
+ // delayed setter to avoid searching on every keypress
953
1083
  if (this.state.lastSearch === thisSearchTime) {
954
1084
  this.setState({
955
1085
  searchTerm: this.state.search
956
- });
1086
+ }, () => this.fetchJobs());
957
1087
  }
958
1088
  }, 500);
959
1089
  });
1090
+ /**
1091
+ * Get the source array for rendering.
1092
+ * With server-side filtering, this is simply the local jobs array
1093
+ * sorted by the user's selected sort column.
1094
+ * The requester filter still applies client-side since the backend
1095
+ * doesn't have a requester/userID filter param.
1096
+ */
960
1097
  _defineProperty__default["default"](this, "getSource", () => {
961
- let source = this.props.source;
1098
+ let source = this.state.jobs;
962
1099
 
963
- // filter by time
964
- if (this.state.selectedTimeFilterStart && this.state.selectedTimeFilterEnd) {
965
- source = ___default["default"].filter(source, r => {
966
- return r.createdUnix >= this.state.selectedTimeFilterStart && r.createdUnix <= this.state.selectedTimeFilterEnd;
967
- });
968
- }
969
-
970
- // filter by type
971
- if (this.state.selectedTypeFilter) {
972
- source = ___default["default"].filter(source, r => {
973
- return r.type === this.state.selectedTypeFilter;
974
- });
975
- }
1100
+ // Filter out deleted items
1101
+ source = ___default["default"].filter(source, ev => ev != null && !ev.Deleted);
976
1102
 
977
- // filter by priority
978
- if (this.state.selectedPriorityFilter) {
979
- const defaultPriority = getDefaultPriority().name;
980
- source = ___default["default"].filter(source, r => {
981
- return r.priority === this.state.selectedPriorityFilter || this.state.selectedPriorityFilter === defaultPriority && ___default["default"].isNil(r.priority);
982
- });
983
- }
984
-
985
- // filter by status
986
- if (this.state.selectedStatusFilter) {
987
- const {
988
- statusTypes
989
- } = this.props;
990
- const defaultStatus = statusTypes.find(s => s.category === STATUS_NOT_ACTIONED);
991
- source = ___default["default"].filter(source, r => {
992
- const status = statusTypes.find(s => s.text === r.status) || defaultStatus;
993
- if (this.state.selectedStatusFilter === STATUS_IMCOMPLETE) {
994
- return status.category !== STATUS_COMPLETED;
995
- }
996
- return status.text === this.state.selectedStatusFilter;
997
- });
998
- }
999
- if (this.state.selectedUserFilter) {
1000
- source = ___default["default"].filter(source, r => {
1001
- return r.AssigneeId === this.state.selectedUserFilter;
1002
- });
1003
- }
1103
+ // Requester filter still client-side (no backend param for userID filtering)
1004
1104
  if (this.state.selectedRequesterFilter) {
1005
1105
  source = ___default["default"].filter(source, r => {
1006
1106
  return r.userID === this.state.selectedRequesterFilter;
1007
1107
  });
1008
1108
  }
1009
- if (!___default["default"].isEmpty(this.state.searchTerm)) {
1010
- source = ___default["default"].filter(source, r => {
1011
- if (r.jobId && r.jobId === this.state.searchTerm) {
1012
- return true;
1013
- }
1014
- if (r.room && r.room.toLowerCase().indexOf(this.state.searchTerm.toLowerCase()) > -1) {
1015
- return true;
1016
- }
1017
- if (r.title && r.title.toLowerCase().indexOf(this.state.searchTerm.toLowerCase()) > -1) {
1018
- return true;
1109
+
1110
+ // Skip sorting while auto-fill is appending results to avoid jumpiness.
1111
+ // Sort is re-applied when the user clicks a column header or when
1112
+ // auto-fill completes.
1113
+ if (!this.state.loadingMore) {
1114
+ source = ___default["default"].sortBy(source, event => {
1115
+ if (this.state.sortColumn === 'assigned') {
1116
+ return event.Assignee ? event.Assignee.displayName : 'Unassigned';
1019
1117
  }
1020
- return false;
1118
+ if (this.state.sortColumn !== 'createdUnix') return event[this.state.sortColumn];
1119
+ return event.createdUnix;
1021
1120
  });
1121
+ if (this.state.sortDesc) source.reverse();
1022
1122
  }
1023
- source = ___default["default"].sortBy(source, event => {
1024
- if (this.state.sortColumn === 'assigned') {
1025
- return event.Assignee ? event.Assignee.displayName : 'Unassigned';
1026
- }
1027
- if (this.state.sortColumn !== 'createdUnix') return event[this.state.sortColumn];
1028
- return event.createdUnix;
1029
- });
1030
- if (this.state.sortDesc) source.reverse();
1031
1123
  return source;
1032
1124
  });
1033
1125
  _defineProperty__default["default"](this, "getCustomFieldValue", field => {
@@ -1107,7 +1199,7 @@ class JobList extends React.Component {
1107
1199
  });
1108
1200
  const customFieldValues = this.getCustomFields(r, customColumns);
1109
1201
  const priority = r.priority || defaultPriority;
1110
- return _objectSpread$7(_objectSpread$7(_objectSpread$7({}, r), customFieldValues), {}, {
1202
+ return _objectSpread$6(_objectSpread$6(_objectSpread$6({}, r), customFieldValues), {}, {
1111
1203
  notes,
1112
1204
  progressTime,
1113
1205
  completedTime,
@@ -1139,13 +1231,60 @@ class JobList extends React.Component {
1139
1231
  exportCsvOpen: false
1140
1232
  });
1141
1233
  });
1234
+ _defineProperty__default["default"](this, "hasActiveFilters", () => {
1235
+ const {
1236
+ selectedTypeFilter,
1237
+ selectedPriorityFilter,
1238
+ selectedStatusFilter,
1239
+ selectedTimeFilterStart,
1240
+ selectedUserFilter,
1241
+ selectedRequesterFilter,
1242
+ searchTerm
1243
+ } = this.state;
1244
+ return !!(selectedTypeFilter || selectedPriorityFilter || selectedStatusFilter || selectedTimeFilterStart || selectedUserFilter || selectedRequesterFilter || searchTerm);
1245
+ });
1246
+ _defineProperty__default["default"](this, "clearAllFilters", () => {
1247
+ this.setState({
1248
+ selectedTypeFilter: null,
1249
+ selectedPriorityFilter: null,
1250
+ selectedStatusFilter: null,
1251
+ selectedTimeFilterStart: null,
1252
+ selectedTimeFilterEnd: null,
1253
+ selectedTimeFilterText: null,
1254
+ selectedUserFilter: null,
1255
+ selectedUserFilterText: null,
1256
+ selectedRequesterFilter: null,
1257
+ selectedRequesterFilterText: null,
1258
+ search: '',
1259
+ searchTerm: ''
1260
+ }, () => this.fetchJobs());
1261
+ });
1142
1262
  this.state = {
1143
- showCompleted: false,
1144
1263
  sortColumn: 'createdUnix',
1145
1264
  sortDesc: true,
1146
1265
  selectedTimeFilter: Analytics$2.getAnalyticsFilterOptions()[1],
1147
1266
  assignees: [],
1148
- requesters: []
1267
+ requesters: [],
1268
+ // Server-side pagination state
1269
+ jobs: [],
1270
+ lastKey: null,
1271
+ hasMore: false,
1272
+ loading: false,
1273
+ loadingMore: false,
1274
+ // Filters (applied to server-side queries)
1275
+ selectedTypeFilter: null,
1276
+ selectedPriorityFilter: null,
1277
+ selectedStatusFilter: null,
1278
+ selectedTimeFilterStart: null,
1279
+ selectedTimeFilterEnd: null,
1280
+ selectedTimeFilterText: null,
1281
+ selectedUserFilter: null,
1282
+ selectedUserFilterText: null,
1283
+ selectedRequesterFilter: null,
1284
+ selectedRequesterFilterText: null,
1285
+ search: '',
1286
+ searchTerm: '',
1287
+ lastSearch: null
1149
1288
  };
1150
1289
  this.exportColumns = [{
1151
1290
  label: 'Select All',
@@ -1205,7 +1344,7 @@ class JobList extends React.Component {
1205
1344
  }
1206
1345
  componentDidMount() {
1207
1346
  this.props.jobStatusesUpdate(this.props.auth.site);
1208
- this.getJobs();
1347
+ this.fetchJobs();
1209
1348
  this.getAssignees();
1210
1349
  }
1211
1350
  renderFilterPopup() {
@@ -1219,7 +1358,7 @@ class JobList extends React.Component {
1219
1358
  minWidth: 400,
1220
1359
  hasPadding: true,
1221
1360
  onClose: this.closeFilter
1222
- }, ___default["default"].sortBy(___default["default"].uniq(this.props.source.map(r => r.type)), t => t.toLowerCase()).map(type => {
1361
+ }, ___default["default"].sortBy(___default["default"].uniq(this.state.jobs.map(r => r.type)), t => t.toLowerCase()).map(type => {
1223
1362
  return /*#__PURE__*/React__default["default"].createElement(Components$7.Tag, {
1224
1363
  key: type,
1225
1364
  onClick: () => {
@@ -1410,7 +1549,7 @@ class JobList extends React.Component {
1410
1549
  const status = ev.status && statusTypes.find(s => s.text === ev.status) || defaultStatus;
1411
1550
  const priority = getJobPriority(ev.priority);
1412
1551
  return /*#__PURE__*/React__default["default"].createElement("tr", {
1413
- key: index
1552
+ key: ev.id || index
1414
1553
  }, /*#__PURE__*/React__default["default"].createElement("td", null, ev.jobId), /*#__PURE__*/React__default["default"].createElement("td", {
1415
1554
  className: "table-TitleColumn"
1416
1555
  }, /*#__PURE__*/React__default["default"].createElement(reactRouterDom.Link, {
@@ -1491,8 +1630,28 @@ class JobList extends React.Component {
1491
1630
  if (col !== this.state.sortColumn) return '';
1492
1631
  return ' table--columnActive';
1493
1632
  }
1633
+ renderLoading() {
1634
+ return /*#__PURE__*/React__default["default"].createElement("div", {
1635
+ className: "flex flex-center-row",
1636
+ style: {
1637
+ padding: 40
1638
+ }
1639
+ }, /*#__PURE__*/React__default["default"].createElement(FontAwesome__default["default"], {
1640
+ style: {
1641
+ fontSize: 32,
1642
+ color: PlussCore.Colours.COLOUR_DUSK_LIGHT
1643
+ },
1644
+ name: "spinner fa-pulse fa-fw"
1645
+ }), /*#__PURE__*/React__default["default"].createElement("span", {
1646
+ className: "marginLeft-16 fontRegular fontSize-14",
1647
+ style: {
1648
+ color: PlussCore.Colours.TEXT_MID
1649
+ }
1650
+ }, "Loading ", values.textTitleRequests, "\u2026"));
1651
+ }
1494
1652
  renderEmpty() {
1495
1653
  const title = this.props.strings["".concat(values.featureKey, "_textTitleRequests")] || values.textTitleRequests;
1654
+ const hasFilters = this.hasActiveFilters();
1496
1655
  return /*#__PURE__*/React__default["default"].createElement("div", {
1497
1656
  style: {
1498
1657
  display: 'flex',
@@ -1504,7 +1663,22 @@ class JobList extends React.Component {
1504
1663
  }
1505
1664
  }, /*#__PURE__*/React__default["default"].createElement("div", {
1506
1665
  className: "emptyState"
1507
- }), /*#__PURE__*/React__default["default"].createElement("div", {
1666
+ }), hasFilters ? /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, /*#__PURE__*/React__default["default"].createElement("div", {
1667
+ className: "marginTop-32",
1668
+ style: {
1669
+ maxWidth: 500,
1670
+ textAlign: 'center'
1671
+ }
1672
+ }, /*#__PURE__*/React__default["default"].createElement("span", {
1673
+ className: "fontRegular fontSize-13"
1674
+ }, "No ", title.toLowerCase(), " match your current filters.")), /*#__PURE__*/React__default["default"].createElement("div", {
1675
+ className: "marginTop-16"
1676
+ }, /*#__PURE__*/React__default["default"].createElement(Components$7.Button, {
1677
+ inline: true,
1678
+ buttonType: "tertiary",
1679
+ onClick: this.clearAllFilters,
1680
+ isActive: true
1681
+ }, "Clear All Filters"))) : /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, /*#__PURE__*/React__default["default"].createElement("div", {
1508
1682
  className: "marginTop-32",
1509
1683
  style: {
1510
1684
  maxWidth: 500,
@@ -1520,11 +1694,66 @@ class JobList extends React.Component {
1520
1694
  maxWidth: 500,
1521
1695
  textAlign: 'center'
1522
1696
  }
1523
- }, values.textEmptyExample));
1697
+ }, values.textEmptyExample)));
1698
+ }
1699
+ renderLoadMore() {
1700
+ const {
1701
+ hasMore,
1702
+ loadingMore
1703
+ } = this.state;
1704
+ if (!hasMore && !loadingMore) return null;
1705
+
1706
+ // During background auto-fill, show a subtle spinner without a button
1707
+ if (loadingMore) {
1708
+ return /*#__PURE__*/React__default["default"].createElement("div", {
1709
+ className: "flex flex-center-row",
1710
+ style: {
1711
+ padding: '16px 0'
1712
+ }
1713
+ }, /*#__PURE__*/React__default["default"].createElement(FontAwesome__default["default"], {
1714
+ name: "spinner fa-pulse fa-fw",
1715
+ style: {
1716
+ fontSize: 16,
1717
+ color: PlussCore.Colours.TEXT_MID,
1718
+ marginRight: 8
1719
+ }
1720
+ }), /*#__PURE__*/React__default["default"].createElement("span", {
1721
+ className: "fontRegular fontSize-13",
1722
+ style: {
1723
+ color: PlussCore.Colours.TEXT_MID
1724
+ }
1725
+ }, "Loading more results\u2026"));
1726
+ }
1727
+ return /*#__PURE__*/React__default["default"].createElement("div", {
1728
+ style: {
1729
+ margin: '24px 0 40px 0',
1730
+ position: 'relative',
1731
+ top: -16
1732
+ }
1733
+ }, /*#__PURE__*/React__default["default"].createElement(Components$7.Button, {
1734
+ buttonType: "primary",
1735
+ onClick: this.loadMore,
1736
+ isActive: true,
1737
+ style: {
1738
+ width: '100%'
1739
+ }
1740
+ }, "Load More Results", /*#__PURE__*/React__default["default"].createElement(FontAwesome__default["default"], {
1741
+ name: "plus",
1742
+ style: {
1743
+ marginLeft: 8
1744
+ }
1745
+ })));
1524
1746
  }
1525
1747
  renderContent() {
1526
- if (___default["default"].isEmpty(this.props.source)) return this.renderEmpty();
1527
- return /*#__PURE__*/React__default["default"].createElement(reactBootstrap.Table, {
1748
+ const {
1749
+ loading,
1750
+ loadingMore,
1751
+ jobs
1752
+ } = this.state;
1753
+ if (loading) return this.renderLoading();
1754
+ if (___default["default"].isEmpty(jobs) && !loadingMore) return this.renderEmpty();
1755
+ if (___default["default"].isEmpty(jobs)) return this.renderLoading();
1756
+ return /*#__PURE__*/React__default["default"].createElement("div", null, /*#__PURE__*/React__default["default"].createElement(reactBootstrap.Table, {
1528
1757
  className: "plussTable",
1529
1758
  striped: true,
1530
1759
  bordered: true,
@@ -1607,7 +1836,7 @@ class JobList extends React.Component {
1607
1836
  style: {
1608
1837
  width: 50
1609
1838
  }
1610
- }))), /*#__PURE__*/React__default["default"].createElement("tbody", null, this.renderRequests()));
1839
+ }))), /*#__PURE__*/React__default["default"].createElement("tbody", null, this.renderRequests())), this.renderLoadMore());
1611
1840
  }
1612
1841
  renderFilters() {
1613
1842
  let typeFilter = /*#__PURE__*/React__default["default"].createElement(Components$7.Tag, {
@@ -1656,13 +1885,9 @@ class JobList extends React.Component {
1656
1885
  typeFilter = /*#__PURE__*/React__default["default"].createElement(Components$7.Tag, {
1657
1886
  className: "marginRight-10",
1658
1887
  onClick: () => {
1659
- this.openFilter('type');
1660
- },
1661
- rightIcon: "close",
1662
- rightClick: e => {
1663
- e.stopPropagation();
1664
1888
  this.selectTypeFilter();
1665
1889
  },
1890
+ rightIcon: "close",
1666
1891
  text: this.state.selectedTypeFilter
1667
1892
  });
1668
1893
  }
@@ -1670,13 +1895,9 @@ class JobList extends React.Component {
1670
1895
  priorityFilter = /*#__PURE__*/React__default["default"].createElement(Components$7.Tag, {
1671
1896
  className: "marginRight-10",
1672
1897
  onClick: () => {
1673
- this.openFilter('priority');
1674
- },
1675
- rightIcon: "close",
1676
- rightClick: e => {
1677
- e.stopPropagation();
1678
1898
  this.selectPriorityFilter();
1679
1899
  },
1900
+ rightIcon: "close",
1680
1901
  text: this.state.selectedPriorityFilter
1681
1902
  });
1682
1903
  }
@@ -1684,13 +1905,9 @@ class JobList extends React.Component {
1684
1905
  statusFilter = /*#__PURE__*/React__default["default"].createElement(Components$7.Tag, {
1685
1906
  className: "marginRight-10",
1686
1907
  onClick: () => {
1687
- this.openFilter('status');
1688
- },
1689
- rightIcon: "close",
1690
- rightClick: e => {
1691
- e.stopPropagation();
1692
1908
  this.selectStatusFilter();
1693
1909
  },
1910
+ rightIcon: "close",
1694
1911
  text: this.state.selectedStatusFilter
1695
1912
  });
1696
1913
  }
@@ -1712,13 +1929,9 @@ class JobList extends React.Component {
1712
1929
  userFilter = /*#__PURE__*/React__default["default"].createElement(Components$7.Tag, {
1713
1930
  className: "marginRight-10",
1714
1931
  onClick: () => {
1715
- this.openFilter('user');
1716
- },
1717
- rightIcon: "close",
1718
- rightClick: e => {
1719
- e.stopPropagation();
1720
1932
  this.removeUserFilter();
1721
1933
  },
1934
+ rightIcon: "close",
1722
1935
  text: this.state.selectedUserFilterText
1723
1936
  });
1724
1937
  }
@@ -1726,13 +1939,9 @@ class JobList extends React.Component {
1726
1939
  requesterFilter = /*#__PURE__*/React__default["default"].createElement(Components$7.Tag, {
1727
1940
  className: "marginRight-10",
1728
1941
  onClick: () => {
1729
- this.openFilter('requester');
1730
- },
1731
- rightIcon: "close",
1732
- rightClick: e => {
1733
- e.stopPropagation();
1734
1942
  this.removeRequesterFilter();
1735
1943
  },
1944
+ rightIcon: "close",
1736
1945
  text: this.state.selectedRequesterFilterText
1737
1946
  });
1738
1947
  }
@@ -1810,7 +2019,7 @@ class JobTypes extends React.Component {
1810
2019
  super(props);
1811
2020
  _defineProperty__default["default"](this, "getJobTypes", async () => {
1812
2021
  try {
1813
- const res = await maintenanceActions.getJobTypes(this.props.auth.site);
2022
+ const res = await maintenanceActions$1.getJobTypes(this.props.auth.site);
1814
2023
  if (res.data != null) this.props.jobTypesLoaded(res.data);
1815
2024
  } catch (error) {
1816
2025
  console.error('getJobTypes', error);
@@ -1835,7 +2044,7 @@ class JobTypes extends React.Component {
1835
2044
  _defineProperty__default["default"](this, "onRemoveJobType", async ev => {
1836
2045
  if (!window.confirm("Are you sure you want to delete ".concat(ev.typeName, "?"))) return;
1837
2046
  try {
1838
- await maintenanceActions.deleteJobType(this.props.auth.site, ev.id);
2047
+ await maintenanceActions$1.deleteJobType(this.props.auth.site, ev.id);
1839
2048
  const index = ___default["default"].findIndex(this.state.jobList, job => {
1840
2049
  return job != null && job.id === ev.id;
1841
2050
  });
@@ -2040,12 +2249,12 @@ var JobTypes$1 = reactRedux.connect(mapStateToProps$6, {
2040
2249
  jobTypesUpdate
2041
2250
  })(reactRouter.withRouter(JobTypes));
2042
2251
 
2043
- function ownKeys$6(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
2044
- function _objectSpread$6(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$6(Object(t), !0).forEach(function (r) { _defineProperty__default["default"](e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$6(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
2252
+ function ownKeys$5(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
2253
+ function _objectSpread$5(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$5(Object(t), !0).forEach(function (r) { _defineProperty__default["default"](e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$5(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
2045
2254
  const {
2046
2255
  Session: Session$5,
2047
2256
  Components: Components$5,
2048
- Colours: Colours$3
2257
+ Colours: Colours$2
2049
2258
  } = PlussCore__namespace;
2050
2259
  class Configuration extends React.Component {
2051
2260
  constructor(props) {
@@ -2236,43 +2445,43 @@ class Configuration extends React.Component {
2236
2445
  return /*#__PURE__*/React__default["default"].createElement("div", null, /*#__PURE__*/React__default["default"].createElement("p", {
2237
2446
  className: "fontMedium fontSize-36 text-dark"
2238
2447
  }, "Statuses"), /*#__PURE__*/React__default["default"].createElement("div", {
2239
- style: styles$6.statusCategoryHeading
2448
+ style: styles$5.statusCategoryHeading
2240
2449
  }, /*#__PURE__*/React__default["default"].createElement("span", {
2241
2450
  className: "fontMedium fontSize-16 text-bold"
2242
2451
  }, "Status Category")), statusTypes.map((status, index) => {
2243
2452
  return /*#__PURE__*/React__default["default"].createElement("div", {
2244
2453
  key: "".concat(status.text, "_").concat(index),
2245
- style: styles$6.statusTypeContainer
2454
+ style: styles$5.statusTypeContainer
2246
2455
  }, /*#__PURE__*/React__default["default"].createElement("div", {
2247
2456
  key: status.text,
2248
2457
  className: "statusLabel",
2249
- style: _objectSpread$6(_objectSpread$6({}, styles$6.statusTextContainer), {}, {
2458
+ style: _objectSpread$5(_objectSpread$5({}, styles$5.statusTextContainer), {}, {
2250
2459
  backgroundColor: status.color
2251
2460
  })
2252
2461
  }, /*#__PURE__*/React__default["default"].createElement("span", {
2253
2462
  className: "statusLabel_text"
2254
2463
  }, status.text)), /*#__PURE__*/React__default["default"].createElement("div", {
2255
- style: styles$6.statusCategoryContainer
2464
+ style: styles$5.statusCategoryContainer
2256
2465
  }, /*#__PURE__*/React__default["default"].createElement("span", {
2257
2466
  className: "fontMedium fontSize-16 text-dark"
2258
2467
  }, status.category)), /*#__PURE__*/React__default["default"].createElement(FontAwesome__default["default"], {
2259
- style: _objectSpread$6(_objectSpread$6({}, styles$6.statusIcon), {}, {
2468
+ style: _objectSpread$5(_objectSpread$5({}, styles$5.statusIcon), {}, {
2260
2469
  visibility: index === 0 ? 'hidden' : 'visible'
2261
2470
  }),
2262
2471
  name: 'arrow-up',
2263
2472
  onClick: () => this.onMoveStatus(index, true)
2264
2473
  }), /*#__PURE__*/React__default["default"].createElement(FontAwesome__default["default"], {
2265
- style: _objectSpread$6(_objectSpread$6({}, styles$6.statusIcon), {}, {
2474
+ style: _objectSpread$5(_objectSpread$5({}, styles$5.statusIcon), {}, {
2266
2475
  visibility: index === statusTypes.length - 1 ? 'hidden' : 'visible'
2267
2476
  }),
2268
2477
  name: 'arrow-down',
2269
2478
  onClick: () => this.onMoveStatus(index, false)
2270
2479
  }), /*#__PURE__*/React__default["default"].createElement(FontAwesome__default["default"], {
2271
- style: _objectSpread$6({}, styles$6.statusIcon),
2480
+ style: _objectSpread$5({}, styles$5.statusIcon),
2272
2481
  name: "pencil",
2273
2482
  onClick: () => this.onEditStatus(index)
2274
2483
  }), /*#__PURE__*/React__default["default"].createElement(FontAwesome__default["default"], {
2275
- style: _objectSpread$6({}, styles$6.statusIcon),
2484
+ style: _objectSpread$5({}, styles$5.statusIcon),
2276
2485
  name: "minus-circle",
2277
2486
  onClick: () => this.onDeleteStatus(index)
2278
2487
  }));
@@ -2321,8 +2530,8 @@ class Configuration extends React.Component {
2321
2530
  renderSuccess() {
2322
2531
  if (!this.state.success) return null;
2323
2532
  return /*#__PURE__*/React__default["default"].createElement("span", {
2324
- style: _objectSpread$6(_objectSpread$6({}, styles$6.savedText), {}, {
2325
- color: Colours$3.COLOUR_GREEN
2533
+ style: _objectSpread$5(_objectSpread$5({}, styles$5.savedText), {}, {
2534
+ color: Colours$2.COLOUR_GREEN
2326
2535
  })
2327
2536
  }, "Saved");
2328
2537
  }
@@ -2438,7 +2647,7 @@ class Configuration extends React.Component {
2438
2647
  }, this.renderSubmit(), this.renderSuccess()), this.renderNewStatusPopup());
2439
2648
  }
2440
2649
  }
2441
- const styles$6 = {
2650
+ const styles$5 = {
2442
2651
  statusCategoryHeading: {
2443
2652
  marginLeft: 130,
2444
2653
  width: 160,
@@ -2463,7 +2672,7 @@ const styles$6 = {
2463
2672
  fontSize: 20,
2464
2673
  padding: 5,
2465
2674
  marginLeft: 10,
2466
- color: Colours$3.COLOUR_BRANDING_ACTION,
2675
+ color: Colours$2.COLOUR_BRANDING_ACTION,
2467
2676
  visibility: 'visible'
2468
2677
  },
2469
2678
  savedText: {
@@ -2497,52 +2706,6 @@ const {
2497
2706
  class RequestsHub extends React.Component {
2498
2707
  constructor(props) {
2499
2708
  super(props);
2500
- _defineProperty__default["default"](this, "setData", () => {
2501
- const allList = [];
2502
- this.state.allList.forEach(ev => {
2503
- if (ev != null && !ev.Deleted) allList.push(ev);
2504
- });
2505
- const upcoming = ___default["default"].filter(allList, ev => {
2506
- if (!ev) return false;
2507
- if (ev.status && ev.status === 'Completed') return false;
2508
- return true;
2509
- });
2510
- const completed = ___default["default"].filter(allList, ev => {
2511
- if (!ev) return false;
2512
- if (ev.status && ev.status === 'Completed') return true;
2513
- return false;
2514
- });
2515
-
2516
- // console.log('setData', upcoming, completed);
2517
- this.setState({
2518
- allList,
2519
- upcoming,
2520
- completed
2521
- });
2522
- });
2523
- _defineProperty__default["default"](this, "getData", () => {
2524
- const {
2525
- auth
2526
- } = this.props;
2527
- this.setState({
2528
- loadingAll: true
2529
- }, async () => {
2530
- try {
2531
- const res = await maintenanceActions.getJobsRecursive(auth.site);
2532
- this.setState({
2533
- loadingAll: false
2534
- });
2535
- if (!___default["default"].isEmpty(res) && res[0].site === auth.site) {
2536
- this.props.jobsLoaded(res);
2537
- }
2538
- } catch (error) {
2539
- console.error('getData', error);
2540
- this.setState({
2541
- loadingAll: false
2542
- });
2543
- }
2544
- });
2545
- });
2546
2709
  _defineProperty__default["default"](this, "onAddNew", () => {
2547
2710
  const {
2548
2711
  auth
@@ -2569,38 +2732,10 @@ class RequestsHub extends React.Component {
2569
2732
  _defineProperty__default["default"](this, "getSideBarSectionColour", id => this.state.selectedSection === id ? {
2570
2733
  backgroundColor: '#fff'
2571
2734
  } : {});
2572
- _defineProperty__default["default"](this, "renderStats", (stat, loading) => loading ? /*#__PURE__*/React__default["default"].createElement(FontAwesome__default["default"], {
2573
- style: styles$5.spinner,
2574
- name: "spinner fa-pulse fa-fw"
2575
- }) : stat);
2576
2735
  this.state = {
2577
- selectedSection: 'all',
2578
- location: '',
2579
- loadingAll: false,
2580
- loadingSubmissions: false,
2581
- submissionEntries: [],
2582
- allList: [],
2583
- completed: [],
2584
- upcoming: [],
2585
- now: moment__default["default"].utc(),
2586
- onlyFuture: true,
2587
- search: ''
2736
+ selectedSection: 'all'
2588
2737
  };
2589
2738
  }
2590
- UNSAFE_componentWillMount() {
2591
- this.updateProps(this.props);
2592
- }
2593
- componentDidMount() {
2594
- this.getData();
2595
- }
2596
- UNSAFE_componentWillReceiveProps(nextProps) {
2597
- if (!___default["default"].isEqual(this.props.jobs, nextProps.jobs)) this.updateProps(nextProps);
2598
- }
2599
- updateProps(props) {
2600
- this.setState({
2601
- allList: props.jobs
2602
- }, this.setData);
2603
- }
2604
2739
  renderLeftBar() {
2605
2740
  const sectionItems = [];
2606
2741
  if (this.canAddNew()) {
@@ -2670,9 +2805,7 @@ class RequestsHub extends React.Component {
2670
2805
  } else if (this.state.selectedSection === 'config') {
2671
2806
  return /*#__PURE__*/React__default["default"].createElement(Configuration$1, null);
2672
2807
  }
2673
- return /*#__PURE__*/React__default["default"].createElement(JobList$1, {
2674
- source: this.state.allList
2675
- });
2808
+ return /*#__PURE__*/React__default["default"].createElement(JobList$1, null);
2676
2809
  }
2677
2810
  render() {
2678
2811
  return /*#__PURE__*/React__default["default"].createElement("div", {
@@ -2684,50 +2817,24 @@ class RequestsHub extends React.Component {
2684
2817
  }, this.renderRight())));
2685
2818
  }
2686
2819
  }
2687
- const styles$5 = {
2688
- sideBarTitleSection: {
2689
- lineHeight: '40px',
2690
- marginTop: 30,
2691
- marginBottom: 30,
2692
- paddingLeft: 24,
2693
- paddingRight: 24
2694
- },
2695
- sideBarSection: {
2696
- weight: '100%',
2697
- minWidth: 200,
2698
- padding: 32,
2699
- paddingLeft: 24,
2700
- cursor: 'pointer',
2701
- display: 'flex',
2702
- flexDirection: 'column',
2703
- justifyContent: 'center'
2704
- },
2705
- spinner: {
2706
- fontSize: 32,
2707
- color: FeatureConfig.env.colourBrandingOff
2708
- }
2709
- };
2710
2820
  const mapStateToProps$4 = state => {
2711
2821
  const {
2712
2822
  auth
2713
2823
  } = state;
2714
2824
  return {
2715
- jobs: state[values.reducerKey].jobs,
2716
2825
  auth,
2717
2826
  strings: state.strings && state.strings.config || {}
2718
2827
  };
2719
2828
  };
2720
- var RequestsHub$1 = reactRedux.connect(mapStateToProps$4, {
2721
- jobsLoaded
2722
- })(reactRouter.withRouter(RequestsHub));
2829
+ var RequestsHub$1 = reactRedux.connect(mapStateToProps$4)(reactRouter.withRouter(RequestsHub));
2723
2830
 
2724
- function ownKeys$5(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
2725
- function _objectSpread$5(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$5(Object(t), !0).forEach(function (r) { _defineProperty__default["default"](e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$5(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
2831
+ function ownKeys$4(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
2832
+ function _objectSpread$4(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$4(Object(t), !0).forEach(function (r) { _defineProperty__default["default"](e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$4(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
2726
2833
  const {
2727
2834
  Apis: Apis$1,
2728
- Helper: Helper$3,
2835
+ Helper: Helper$2,
2729
2836
  Session: Session$3,
2730
- Colours: Colours$2,
2837
+ Colours: Colours$1,
2731
2838
  Components: Components$3
2732
2839
  } = PlussCore__namespace;
2733
2840
  const IMAGE_SIZE_NOTE = 72;
@@ -2736,7 +2843,7 @@ class Job extends React.Component {
2736
2843
  super(props);
2737
2844
  _defineProperty__default["default"](this, "getJob", async () => {
2738
2845
  try {
2739
- const res = await maintenanceActions.getJob(this.props.auth.site, this.state.jobId);
2846
+ const res = await maintenanceActions$1.getJob(this.props.auth.site, this.state.jobId);
2740
2847
  this.setState({
2741
2848
  updating: false
2742
2849
  });
@@ -2748,7 +2855,7 @@ class Job extends React.Component {
2748
2855
  });
2749
2856
  _defineProperty__default["default"](this, "getAssignees", async () => {
2750
2857
  try {
2751
- const res = await maintenanceActions.getAssignees(this.props.auth.site);
2858
+ const res = await maintenanceActions$1.getAssignees(this.props.auth.site);
2752
2859
  this.setState({
2753
2860
  assignees: res.data.Users
2754
2861
  });
@@ -2761,7 +2868,7 @@ class Job extends React.Component {
2761
2868
  this.setState({
2762
2869
  loadingExternalSync: true
2763
2870
  });
2764
- const res = await maintenanceActions.getExternalSync(this.state.jobId);
2871
+ const res = await maintenanceActions$1.getExternalSync(this.state.jobId);
2765
2872
  this.setState({
2766
2873
  externalSync: res.data,
2767
2874
  loadingExternalSync: false
@@ -2786,7 +2893,7 @@ class Job extends React.Component {
2786
2893
  retrySyncError: null
2787
2894
  });
2788
2895
  try {
2789
- await maintenanceActions.retrySync(job.id);
2896
+ await maintenanceActions$1.retrySync(job.id);
2790
2897
  // Refresh job data to get updated history
2791
2898
  await this.getJob();
2792
2899
  this.setState({
@@ -2809,7 +2916,7 @@ class Job extends React.Component {
2809
2916
  let statusType = statusTypes.find(s => s.text === status);
2810
2917
  if (!statusType) {
2811
2918
  const defaultStatus = statusTypes.find(s => s.category === STATUS_NOT_ACTIONED);
2812
- statusType = _objectSpread$5(_objectSpread$5({}, defaultStatus), {}, {
2919
+ statusType = _objectSpread$4(_objectSpread$4({}, defaultStatus), {}, {
2813
2920
  text: status
2814
2921
  });
2815
2922
  }
@@ -2952,7 +3059,7 @@ class Job extends React.Component {
2952
3059
  // Method to handle user assignment
2953
3060
  _defineProperty__default["default"](this, "onAssignUser", async userId => {
2954
3061
  try {
2955
- const res = await maintenanceActions.assignJob(this.state.jobId, userId);
3062
+ const res = await maintenanceActions$1.assignJob(this.state.jobId, userId);
2956
3063
  this.getJob();
2957
3064
  } catch (err) {
2958
3065
  console.error("onAssignUser", err);
@@ -2964,12 +3071,12 @@ class Job extends React.Component {
2964
3071
  this.setState({
2965
3072
  submittingNote: true
2966
3073
  });
2967
- const res = await (this.state.editingNote ? maintenanceActions.editNote(this.state.jobId, this.state.editingNote, this.state.noteInput, this.state.noteAttachments.map(a => {
3074
+ const res = await (this.state.editingNote ? maintenanceActions$1.editNote(this.state.jobId, this.state.editingNote, this.state.noteInput, this.state.noteAttachments.map(a => {
2968
3075
  return {
2969
3076
  Title: a.Title,
2970
3077
  Source: a.Source
2971
3078
  };
2972
- }), this.state.noteImages) : maintenanceActions.addNote(this.state.jobId, this.state.noteInput, this.state.noteAttachments.map(a => {
3079
+ }), this.state.noteImages) : maintenanceActions$1.addNote(this.state.jobId, this.state.noteInput, this.state.noteAttachments.map(a => {
2973
3080
  return {
2974
3081
  Title: a.Title,
2975
3082
  Source: a.Source
@@ -2997,9 +3104,9 @@ class Job extends React.Component {
2997
3104
  });
2998
3105
  return;
2999
3106
  }
3000
- maintenanceActions.deleteNote(this.state.jobId, n.Id);
3107
+ maintenanceActions$1.deleteNote(this.state.jobId, n.Id);
3001
3108
  const newNotes = ___default["default"].filter(this.state.job.Notes, note => note.Id !== n.Id);
3002
- const newJob = _objectSpread$5({}, this.state.job);
3109
+ const newJob = _objectSpread$4({}, this.state.job);
3003
3110
  newJob.Notes = newNotes;
3004
3111
  this.setState({
3005
3112
  job: newJob,
@@ -3035,7 +3142,7 @@ class Job extends React.Component {
3035
3142
  seen: true,
3036
3143
  status: job.status || "Unassigned"
3037
3144
  };
3038
- await maintenanceActions.editJob(update, auth.site);
3145
+ await maintenanceActions$1.editJob(update, auth.site);
3039
3146
  } catch (error) {
3040
3147
  this.setState({
3041
3148
  updating: false
@@ -3083,13 +3190,13 @@ class Job extends React.Component {
3083
3190
  });
3084
3191
  _defineProperty__default["default"](this, "onSelectPriority", async priority => {
3085
3192
  this.setState({
3086
- job: _objectSpread$5(_objectSpread$5({}, this.state.job), {}, {
3193
+ job: _objectSpread$4(_objectSpread$4({}, this.state.job), {}, {
3087
3194
  priority
3088
3195
  }),
3089
3196
  priorityChangerOpen: false
3090
3197
  });
3091
3198
  try {
3092
- const res = await maintenanceActions.editJobPriority(this.state.job.id, priority);
3199
+ const res = await maintenanceActions$1.editJobPriority(this.state.job.id, priority);
3093
3200
  const {
3094
3201
  job
3095
3202
  } = res.data;
@@ -3108,13 +3215,13 @@ class Job extends React.Component {
3108
3215
  });
3109
3216
  _defineProperty__default["default"](this, "onSelectStatus", async status => {
3110
3217
  this.setState({
3111
- job: _objectSpread$5(_objectSpread$5({}, this.state.job), {}, {
3218
+ job: _objectSpread$4(_objectSpread$4({}, this.state.job), {}, {
3112
3219
  status: status
3113
3220
  }),
3114
3221
  statusChangerOpen: false
3115
3222
  });
3116
3223
  try {
3117
- const res = await maintenanceActions.editJobStatus(this.state.job.id, status);
3224
+ const res = await maintenanceActions$1.editJobStatus(this.state.job.id, status);
3118
3225
  const {
3119
3226
  job
3120
3227
  } = res.data;
@@ -3127,7 +3234,7 @@ class Job extends React.Component {
3127
3234
  }
3128
3235
  });
3129
3236
  this.state = {
3130
- jobId: Helper$3.safeReadParams(props, "jobId") ? props.match.params.jobId : null,
3237
+ jobId: Helper$2.safeReadParams(props, "jobId") ? props.match.params.jobId : null,
3131
3238
  job: null,
3132
3239
  showingSelector: false,
3133
3240
  updating: false,
@@ -3330,7 +3437,7 @@ class Job extends React.Component {
3330
3437
  }, /*#__PURE__*/React__default["default"].createElement("div", {
3331
3438
  className: "imageGrid_image",
3332
3439
  style: {
3333
- backgroundImage: "url('".concat(Helper$3.get1400(image), "')"),
3440
+ backgroundImage: "url('".concat(Helper$2.get1400(image), "')"),
3334
3441
  width: size,
3335
3442
  height: size
3336
3443
  }
@@ -3527,7 +3634,7 @@ class Job extends React.Component {
3527
3634
  }, /*#__PURE__*/React__default["default"].createElement("div", {
3528
3635
  className: "maintenanceNote_top"
3529
3636
  }, this.props.auth && this.props.auth.user && this.props.auth.user.Id === note.User.id && /*#__PURE__*/React__default["default"].createElement(Components$3.SVGIcon, {
3530
- colour: Colours$2.COLOUR_DUSK_LIGHT,
3637
+ colour: Colours$1.COLOUR_DUSK_LIGHT,
3531
3638
  icon: "more15",
3532
3639
  className: "maintenanceNote_moreIcon",
3533
3640
  onClick: () => this.onOpenNoteMenu(index)
@@ -3545,7 +3652,7 @@ class Job extends React.Component {
3545
3652
  }]
3546
3653
  })), /*#__PURE__*/React__default["default"].createElement("p", {
3547
3654
  className: "maintenanceNote_text"
3548
- }, Helper$3.toParagraphed(note.Note)), note.Attachments.map((a, i) => this.renderAttachment(a, i)), note.Images && note.Images.length > 0 ? this.renderImageGrid(note.Images, IMAGE_SIZE_NOTE) : null));
3655
+ }, Helper$2.toParagraphed(note.Note)), note.Attachments.map((a, i) => this.renderAttachment(a, i)), note.Images && note.Images.length > 0 ? this.renderImageGrid(note.Images, IMAGE_SIZE_NOTE) : null));
3549
3656
  }
3550
3657
  renderAssignment() {
3551
3658
  const {
@@ -3578,7 +3685,7 @@ class Job extends React.Component {
3578
3685
  }, moment__default["default"].utc(e.timestamp).local().format("D MMM YYYY h:mma")), /*#__PURE__*/React__default["default"].createElement("div", {
3579
3686
  className: "statusLabel statusLabel-large statusLabel-full",
3580
3687
  style: {
3581
- backgroundColor: Colours$2.COLOUR_DUSK
3688
+ backgroundColor: Colours$1.COLOUR_DUSK
3582
3689
  }
3583
3690
  }, /*#__PURE__*/React__default["default"].createElement("span", {
3584
3691
  className: "statusLabel_text"
@@ -3586,7 +3693,7 @@ class Job extends React.Component {
3586
3693
  }
3587
3694
  renderExternalSyncEntry(e, i) {
3588
3695
  const isSuccess = e.EntryType === "ExternalIDSet";
3589
- const backgroundColor = isSuccess ? Colours$2.COLOUR_GREEN : Colours$2.COLOUR_RED; // Green for success, red for failure
3696
+ const backgroundColor = isSuccess ? Colours$1.COLOUR_GREEN : Colours$1.COLOUR_RED; // Green for success, red for failure
3590
3697
 
3591
3698
  return /*#__PURE__*/React__default["default"].createElement("div", {
3592
3699
  className: "ticketHistoryEntry",
@@ -3646,7 +3753,7 @@ class Job extends React.Component {
3646
3753
  return /*#__PURE__*/React__default["default"].createElement(FontAwesome__default["default"], {
3647
3754
  style: {
3648
3755
  fontSize: 20,
3649
- color: Colours$2.COLOUR_DUSK_LIGHT,
3756
+ color: Colours$1.COLOUR_DUSK_LIGHT,
3650
3757
  marginLeft: 8
3651
3758
  },
3652
3759
  name: "spinner fa-pulse fa-fw"
@@ -3656,7 +3763,7 @@ class Job extends React.Component {
3656
3763
  className: "statusLabel pointer",
3657
3764
  onClick: this.onRetrySync,
3658
3765
  style: {
3659
- backgroundColor: Colours$2.COLOUR_RED,
3766
+ backgroundColor: Colours$1.COLOUR_RED,
3660
3767
  marginLeft: 8
3661
3768
  }
3662
3769
  }, /*#__PURE__*/React__default["default"].createElement("span", {
@@ -3677,7 +3784,7 @@ class Job extends React.Component {
3677
3784
  className: "userStatusIcon",
3678
3785
  name: "times-circle",
3679
3786
  style: {
3680
- color: Colours$2.COLOUR_RED
3787
+ color: Colours$1.COLOUR_RED
3681
3788
  }
3682
3789
  }), " ", retrySyncError);
3683
3790
  }
@@ -3690,7 +3797,7 @@ class Job extends React.Component {
3690
3797
  className: "userStatusIcon",
3691
3798
  name: "check-circle",
3692
3799
  style: {
3693
- color: Colours$2.COLOUR_GREEN
3800
+ color: Colours$1.COLOUR_GREEN
3694
3801
  }
3695
3802
  }), " ", "Sync retry initiated. Check back shortly for results.");
3696
3803
  }
@@ -3703,7 +3810,7 @@ class Job extends React.Component {
3703
3810
  className: "userStatusIcon",
3704
3811
  name: "times-circle",
3705
3812
  style: {
3706
- color: Colours$2.COLOUR_RED
3813
+ color: Colours$1.COLOUR_RED
3707
3814
  }
3708
3815
  }), " ", "External sync failed. Use the retry button to attempt again.");
3709
3816
  }
@@ -3747,11 +3854,11 @@ class Job extends React.Component {
3747
3854
  } = this.state;
3748
3855
  if (!job || !job.history) return null;
3749
3856
  const source = ___default["default"].sortBy([...job.history.map(e => {
3750
- return _objectSpread$5(_objectSpread$5({}, e), {}, {
3857
+ return _objectSpread$4(_objectSpread$4({}, e), {}, {
3751
3858
  EntryType: e.EntryType || "status"
3752
3859
  });
3753
3860
  }), ...(job.Notes || []).map(e => {
3754
- return _objectSpread$5(_objectSpread$5({}, e), {}, {
3861
+ return _objectSpread$4(_objectSpread$4({}, e), {}, {
3755
3862
  timestamp: e.Timestamp,
3756
3863
  EntryType: "note"
3757
3864
  });
@@ -3900,7 +4007,7 @@ class Job extends React.Component {
3900
4007
  onClick: () => {
3901
4008
  this.onSelectAssignee();
3902
4009
  },
3903
- colour: Colours$2.COLOUR_DUSK
4010
+ colour: Colours$1.COLOUR_DUSK
3904
4011
  })
3905
4012
  }));
3906
4013
  } else {
@@ -3974,14 +4081,14 @@ var Job$1 = reactRedux.connect(mapStateToProps$3, {
3974
4081
  jobStatusesUpdate
3975
4082
  })(reactRouter.withRouter(Job));
3976
4083
 
3977
- function ownKeys$4(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3978
- function _objectSpread$4(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$4(Object(t), !0).forEach(function (r) { _defineProperty__default["default"](e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$4(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4084
+ function ownKeys$3(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
4085
+ function _objectSpread$3(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$3(Object(t), !0).forEach(function (r) { _defineProperty__default["default"](e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$3(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
3979
4086
  const {
3980
4087
  Actions,
3981
4088
  Components: Components$2,
3982
- Helper: Helper$2,
4089
+ Helper: Helper$1,
3983
4090
  Session: Session$2,
3984
- Colours: Colours$1,
4091
+ Colours,
3985
4092
  Apis
3986
4093
  } = PlussCore__namespace;
3987
4094
  class AddJob extends React.Component {
@@ -3991,7 +4098,7 @@ class AddJob extends React.Component {
3991
4098
  _this = this;
3992
4099
  _defineProperty__default["default"](this, "getJob", async () => {
3993
4100
  try {
3994
- const res = await maintenanceActions.getJob(this.props.auth.site, this.state.jobId);
4101
+ const res = await maintenanceActions$1.getJob(this.props.auth.site, this.state.jobId);
3995
4102
  res.data.location = res.data.site;
3996
4103
  const {
3997
4104
  userID,
@@ -4000,7 +4107,7 @@ class AddJob extends React.Component {
4000
4107
  type,
4001
4108
  customFields
4002
4109
  } = res.data;
4003
- this.setState(_objectSpread$4(_objectSpread$4({}, res.data), {}, {
4110
+ this.setState(_objectSpread$3(_objectSpread$3({}, res.data), {}, {
4004
4111
  prevType: type,
4005
4112
  prevCustomFileds: customFields,
4006
4113
  type,
@@ -4025,7 +4132,7 @@ class AddJob extends React.Component {
4025
4132
  });
4026
4133
  _defineProperty__default["default"](this, "getJobTypes", async () => {
4027
4134
  try {
4028
- const res = await maintenanceActions.getJobTypes(this.props.auth.site);
4135
+ const res = await maintenanceActions$1.getJobTypes(this.props.auth.site);
4029
4136
  this.setState({
4030
4137
  types: res.data
4031
4138
  });
@@ -4248,7 +4355,7 @@ class AddJob extends React.Component {
4248
4355
  event.target.value = "";
4249
4356
  });
4250
4357
  _defineProperty__default["default"](this, "onToggleDatePicker", qId => {
4251
- const showDate = _objectSpread$4({}, this.state.showDate);
4358
+ const showDate = _objectSpread$3({}, this.state.showDate);
4252
4359
  showDate[qId] = !showDate[qId];
4253
4360
  this.setState({
4254
4361
  showDate
@@ -4285,7 +4392,7 @@ class AddJob extends React.Component {
4285
4392
  customFields: this.state.customFields
4286
4393
  };
4287
4394
  if (this.state.id != null) {
4288
- maintenanceActions.editJob(job, this.props.auth.site).then(res => {
4395
+ maintenanceActions$1.editJob(job, this.props.auth.site).then(res => {
4289
4396
  this.setState({
4290
4397
  success: true,
4291
4398
  updating: false
@@ -4299,12 +4406,12 @@ class AddJob extends React.Component {
4299
4406
  });
4300
4407
  } else {
4301
4408
  // Create New Job
4302
- maintenanceActions.createJob(job).then(res => {
4409
+ maintenanceActions$1.createJob(job).then(res => {
4303
4410
  this.setState({
4304
4411
  success: true,
4305
4412
  updating: false
4306
4413
  });
4307
- this.props.jobsUpdate(this.props.auth.site);
4414
+ // JobList fetches fresh data on mount — no action needed here
4308
4415
  }).catch(res => {
4309
4416
  this.setState({
4310
4417
  updating: false
@@ -4337,7 +4444,7 @@ class AddJob extends React.Component {
4337
4444
  if (___default["default"].isNil(answer) || ___default["default"].isEmpty(answer)) return true;
4338
4445
  switch (type) {
4339
4446
  case "email":
4340
- return Helper$2.isEmail(answer);
4447
+ return Helper$1.isEmail(answer);
4341
4448
  case "date":
4342
4449
  return moment__default["default"](answer, "YYYY-MM-DD", true).isValid();
4343
4450
  case "time":
@@ -4358,7 +4465,7 @@ class AddJob extends React.Component {
4358
4465
  this.customImageInputs = {};
4359
4466
  this.customDocumentInputs = {};
4360
4467
  this.state = {
4361
- jobId: Helper$2.safeReadParams(this.props, "jobId") ? this.props.match.params.jobId : null,
4468
+ jobId: Helper$1.safeReadParams(this.props, "jobId") ? this.props.match.params.jobId : null,
4362
4469
  job: null,
4363
4470
  showingSelector: false,
4364
4471
  updating: false,
@@ -4710,7 +4817,7 @@ class AddJob extends React.Component {
4710
4817
  return /*#__PURE__*/React__default["default"].createElement("p", {
4711
4818
  className: "visitorSignIn_text-staticText",
4712
4819
  key: fieldId
4713
- }, Helper$2.toParagraphed(field.label, {
4820
+ }, Helper$1.toParagraphed(field.label, {
4714
4821
  marginTop: 10
4715
4822
  }));
4716
4823
  case "date":
@@ -4729,7 +4836,7 @@ class AddJob extends React.Component {
4729
4836
  alwaysShowLabel: true,
4730
4837
  readOnly: true,
4731
4838
  rightContent: !___default["default"].isEmpty(field.answer) && /*#__PURE__*/React__default["default"].createElement(Components$2.SVGIcon, {
4732
- colour: Colours$1.COLOUR_DUSK_LIGHT,
4839
+ colour: Colours.COLOUR_DUSK_LIGHT,
4733
4840
  icon: "close",
4734
4841
  className: "timepicker_clear",
4735
4842
  onClick: () => this.onChangeDateAnswer(fieldId, undefined, false)
@@ -4762,7 +4869,7 @@ class AddJob extends React.Component {
4762
4869
  }
4763
4870
  }),
4764
4871
  rightContent: !___default["default"].isEmpty(field.answer) && /*#__PURE__*/React__default["default"].createElement(Components$2.SVGIcon, {
4765
- colour: Colours$1.COLOUR_DUSK_LIGHT,
4872
+ colour: Colours.COLOUR_DUSK_LIGHT,
4766
4873
  icon: "close",
4767
4874
  className: "timepicker_clear",
4768
4875
  onClick: () => this.onChangeTimeAnswer(fieldId, undefined)
@@ -4965,11 +5072,10 @@ const mapStateToProps$2 = state => {
4965
5072
  return {
4966
5073
  auth,
4967
5074
  strings: state.strings && state.strings.config || {},
4968
- optionOnlyForResidents: Helper$2.getSiteSettingFromState(state, values.optionOnlyForResidents)
5075
+ optionOnlyForResidents: Helper$1.getSiteSettingFromState(state, values.optionOnlyForResidents)
4969
5076
  };
4970
5077
  };
4971
5078
  var AddJob$1 = reactRedux.connect(mapStateToProps$2, {
4972
- jobsUpdate,
4973
5079
  jobsLoaded,
4974
5080
  addRecentlyCreated: Actions.addRecentlyCreated
4975
5081
  })(reactRouter.withRouter(AddJob));
@@ -4977,7 +5083,7 @@ var AddJob$1 = reactRedux.connect(mapStateToProps$2, {
4977
5083
  const {
4978
5084
  Components: Components$1,
4979
5085
  Session: Session$1,
4980
- Helper: Helper$1
5086
+ Helper
4981
5087
  } = PlussCore__namespace;
4982
5088
  const DEFAULT_FIELD = {
4983
5089
  type: 'text',
@@ -4991,7 +5097,7 @@ class AddJobType extends React.Component {
4991
5097
  super(props);
4992
5098
  _defineProperty__default["default"](this, "getJobType", async () => {
4993
5099
  try {
4994
- const res = await maintenanceActions.getJobType(this.props.auth.site, this.state.jobTypeId);
5100
+ const res = await maintenanceActions$1.getJobType(this.props.auth.site, this.state.jobTypeId);
4995
5101
  const {
4996
5102
  typeName,
4997
5103
  email,
@@ -5020,7 +5126,7 @@ class AddJobType extends React.Component {
5020
5126
  const {
5021
5127
  jobTypeEmail
5022
5128
  } = this.state;
5023
- return !___default["default"].isEmpty(jobTypeEmail) && Helper$1.isEmail(jobTypeEmail);
5129
+ return !___default["default"].isEmpty(jobTypeEmail) && Helper.isEmail(jobTypeEmail);
5024
5130
  });
5025
5131
  _defineProperty__default["default"](this, "isJobTypeValid", () => {
5026
5132
  const {
@@ -5163,9 +5269,9 @@ class AddJobType extends React.Component {
5163
5269
  }, async () => {
5164
5270
  try {
5165
5271
  if (jobTypeId) {
5166
- await maintenanceActions.editJobType(site, jobTypeId, jobTypeName, jobTypeEmail, jobTypeDescription, jobTypeLevel, hasCustomFields, customFields);
5272
+ await maintenanceActions$1.editJobType(site, jobTypeId, jobTypeName, jobTypeEmail, jobTypeDescription, jobTypeLevel, hasCustomFields, customFields);
5167
5273
  } else {
5168
- await maintenanceActions.addJobType(site, jobTypeName, jobTypeEmail, jobTypeDescription, jobTypeLevel, hasCustomFields, customFields);
5274
+ await maintenanceActions$1.addJobType(site, jobTypeName, jobTypeEmail, jobTypeDescription, jobTypeLevel, hasCustomFields, customFields);
5169
5275
  }
5170
5276
  this.props.jobTypesUpdate(site);
5171
5277
  this.setState({
@@ -5222,7 +5328,7 @@ class AddJobType extends React.Component {
5222
5328
  }];
5223
5329
  this.state = {
5224
5330
  loading: false,
5225
- jobTypeId: Helper$1.safeReadParams(this.props, 'jobTypeId') ? this.props.match.params.jobTypeId : null,
5331
+ jobTypeId: Helper.safeReadParams(this.props, 'jobTypeId') ? this.props.match.params.jobTypeId : null,
5226
5332
  jobTypeName: '',
5227
5333
  jobTypeEmail: '',
5228
5334
  jobTypeDescription: '',
@@ -5771,14 +5877,10 @@ var AddJobType$1 = reactRedux.connect(mapStateToProps$1, {
5771
5877
  jobTypesUpdate
5772
5878
  })(reactRouter.withRouter(AddJobType));
5773
5879
 
5774
- function ownKeys$3(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
5775
- function _objectSpread$3(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$3(Object(t), !0).forEach(function (r) { _defineProperty__default["default"](e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$3(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
5776
5880
  const {
5777
5881
  Analytics: Analytics$1,
5778
5882
  Session,
5779
- Components,
5780
- Helper,
5781
- Colours
5883
+ Components
5782
5884
  } = PlussCore__namespace;
5783
5885
  const getInitialState = () => ({
5784
5886
  requests: 0,
@@ -5798,21 +5900,10 @@ const AnalyticsHub = _ref => {
5798
5900
  auth,
5799
5901
  prevText,
5800
5902
  dayCount,
5801
- strings,
5802
- userType,
5803
- userCategory,
5804
- selectedSites
5903
+ strings
5805
5904
  } = _ref;
5806
5905
  const [analyticsData, setAnalyticsData] = React.useState(getInitialState());
5807
5906
  const [isExportOpen, setIsExportOpen] = React.useState(false);
5808
- const [failedSites, setFailedSites] = React.useState([]);
5809
- const [comparisonData, setComparisonData] = React.useState({
5810
- requests: [],
5811
- completedRequests: [],
5812
- comments: [],
5813
- isLoading: true
5814
- });
5815
- const comparisonMode = selectedSites && selectedSites.length > 1;
5816
5907
  const hasAccess = Session.validateAccess(auth.site, values.permissionMaintenanceTracking, auth);
5817
5908
  if (!hasAccess) {
5818
5909
  return null;
@@ -5824,130 +5915,50 @@ const AnalyticsHub = _ref => {
5824
5915
  return strings.sideNav[key];
5825
5916
  })();
5826
5917
  const exportColumns = [{
5827
- label: "Select All",
5828
- key: ""
5829
- }, ...(comparisonMode ? [{
5830
- label: "Site",
5831
- key: "site"
5832
- }] : []), {
5833
- label: "Start Date",
5834
- key: "startDate"
5918
+ label: 'Select All',
5919
+ key: ''
5920
+ }, {
5921
+ label: 'Start Date',
5922
+ key: 'startDate'
5835
5923
  }, {
5836
- label: "End Date",
5837
- key: "endDate"
5924
+ label: 'End Date',
5925
+ key: 'endDate'
5838
5926
  }, {
5839
5927
  label: "".concat(values.textSingularName, "s"),
5840
- key: "requests"
5928
+ key: 'requests'
5841
5929
  }, {
5842
5930
  label: "Completed ".concat(values.textSingularName, "s"),
5843
- key: "completedRequests"
5931
+ key: 'completedRequests'
5844
5932
  }, {
5845
- label: "Comments",
5846
- key: "comments"
5933
+ label: 'Comments',
5934
+ key: 'comments'
5847
5935
  }];
5848
5936
  React.useEffect(() => {
5849
5937
  getData();
5850
- }, [startTime, endTime, userType, userCategory, selectedSites]);
5938
+ }, [startTime, endTime]);
5851
5939
  const getData = async () => {
5852
- try {
5853
- setFailedSites([]);
5854
- if (comparisonMode) {
5855
- setComparisonData({
5856
- requests: [],
5857
- completedRequests: [],
5858
- comments: [],
5859
- isLoading: true
5860
- });
5861
- const multiSiteResultsObj = await Analytics$1.fetchMultiSiteData(selectedSites, async site => {
5862
- const {
5863
- data
5864
- } = await analyticsActions.getAggregateEntityStats(site, values.analyticsKey, startTime, endTime, true, {
5865
- userType,
5866
- userCategory
5867
- });
5868
- return data;
5869
- });
5870
- const roles = auth.user.Roles;
5871
- const failed = Object.entries(multiSiteResultsObj).filter(_ref2 => {
5872
- let [, data] = _ref2;
5873
- return data === null;
5874
- }).map(_ref3 => {
5875
- let [site] = _ref3;
5876
- return Helper.getSiteNameFromRoles(site, roles);
5877
- });
5878
- setFailedSites(failed);
5879
- const multiSiteResults = Object.entries(multiSiteResultsObj).filter(_ref4 => {
5880
- let [, data] = _ref4;
5881
- return data !== null;
5882
- }).map(_ref5 => {
5883
- let [site, data] = _ref5;
5884
- return {
5885
- site,
5886
- data
5887
- };
5888
- });
5889
- const buildComparison = (activityKey, countType) => multiSiteResults.map(result => ({
5890
- name: Helper.getSiteNameFromRoles(result.site, roles),
5891
- value: Analytics$1.countActivities(result.data, activityKey, countType)
5892
- }));
5893
- setComparisonData({
5894
- requests: buildComparison("Request", "total"),
5895
- completedRequests: buildComparison("RequestCompleted", "unique"),
5896
- comments: buildComparison("Comment", "total"),
5897
- isLoading: false
5898
- });
5899
- } else {
5900
- setAnalyticsData(getInitialState());
5901
- const site = selectedSites && selectedSites.length === 1 ? selectedSites[0] : auth.site;
5902
- const timeDifference = endTime - startTime;
5903
- const [currentStatsResponse, prevStatsResponse] = await Promise.all([analyticsActions.getAggregateEntityStats(site, values.analyticsKey, startTime, endTime, true, {
5904
- userType,
5905
- userCategory
5906
- }), analyticsActions.getAggregateEntityStats(site, values.analyticsKey, startTime - timeDifference, startTime, true, {
5907
- userType,
5908
- userCategory
5909
- })]);
5910
- const data = {
5911
- requests: Analytics$1.countActivities(currentStatsResponse.data, "Request", "total"),
5912
- prevRequests: Analytics$1.countActivities(prevStatsResponse.data, "Request", "total"),
5913
- completedRequests: Analytics$1.countActivities(currentStatsResponse.data, "RequestCompleted", "unique"),
5914
- prevCompletedRequests: Analytics$1.countActivities(prevStatsResponse.data, "RequestCompleted", "unique"),
5915
- comments: Analytics$1.countActivities(currentStatsResponse.data, "Comment", "total"),
5916
- prevComments: Analytics$1.countActivities(prevStatsResponse.data, "Comment", "total"),
5917
- isLoading: false
5918
- };
5919
- setAnalyticsData(data);
5920
- }
5921
- } catch (err) {
5922
- if (comparisonMode) {
5923
- setComparisonData(prev => _objectSpread$3(_objectSpread$3({}, prev), {}, {
5924
- isLoading: false
5925
- }));
5926
- } else {
5927
- setAnalyticsData(prev => _objectSpread$3(_objectSpread$3({}, prev), {}, {
5928
- isLoading: false
5929
- }));
5930
- }
5931
- }
5940
+ setAnalyticsData(getInitialState());
5941
+ // Load analytics data here using startTime and endTime
5942
+ const timeDifference = endTime - startTime;
5943
+ const [currentStatsResponse, prevStatsResponse] = await Promise.all([analyticsActions.getAggregateEntityStats(auth.site, values.analyticsKey, startTime, endTime, true), analyticsActions.getAggregateEntityStats(auth.site, values.analyticsKey, startTime - timeDifference, startTime, true)]);
5944
+ const data = {
5945
+ requests: Analytics$1.countActivities(currentStatsResponse.data, 'Request', 'total'),
5946
+ prevRequests: Analytics$1.countActivities(prevStatsResponse.data, 'Request', 'total'),
5947
+ completedRequests: Analytics$1.countActivities(currentStatsResponse.data, 'RequestCompleted', 'unique'),
5948
+ prevCompletedRequests: Analytics$1.countActivities(prevStatsResponse.data, 'RequestCompleted', 'unique'),
5949
+ comments: Analytics$1.countActivities(currentStatsResponse.data, 'Comment', 'total'),
5950
+ prevComments: Analytics$1.countActivities(prevStatsResponse.data, 'Comment', 'total'),
5951
+ isLoading: false
5952
+ };
5953
+ setAnalyticsData(data);
5932
5954
  };
5933
5955
  const isReadyToOpenCSV = () => {
5934
- return comparisonMode ? !comparisonData.isLoading : !analyticsData.isLoading;
5956
+ return !analyticsData.isLoading;
5935
5957
  };
5936
5958
  const getExportSource = () => {
5937
- if (comparisonMode) {
5938
- const sites = comparisonData.requests || [];
5939
- return sites.map((site, i) => ({
5940
- site: site.name,
5941
- startDate: moment__default["default"](startTime + 1).format("D-MM-YYYY"),
5942
- endDate: moment__default["default"](endTime).format("D-MM-YYYY"),
5943
- requests: site.value,
5944
- completedRequests: comparisonData.completedRequests[i] && comparisonData.completedRequests[i].value || 0,
5945
- comments: comparisonData.comments[i] && comparisonData.comments[i].value || 0
5946
- }));
5947
- }
5948
5959
  return [{
5949
- startDate: moment__default["default"](startTime + 1).format("D-MM-YYYY"),
5950
- endDate: moment__default["default"](endTime).format("D-MM-YYYY"),
5960
+ startDate: moment__default["default"](startTime + 1).format('D-MM-YYYY'),
5961
+ endDate: moment__default["default"](endTime).format('D-MM-YYYY'),
5951
5962
  requests: analyticsData.requests,
5952
5963
  completedRequests: analyticsData.completedRequests,
5953
5964
  comments: analyticsData.comments
@@ -5958,14 +5969,13 @@ const AnalyticsHub = _ref => {
5958
5969
  return null;
5959
5970
  }
5960
5971
  const source = getExportSource();
5961
- const filterSuffix = [userType, userCategory].filter(Boolean).map(f => f.toLowerCase().replace(/\s+/g, "-")).join("_");
5962
5972
  return /*#__PURE__*/React__default["default"].createElement(Components.ExportCsvPopup, {
5963
5973
  onClose: () => {
5964
5974
  setIsExportOpen(false);
5965
5975
  },
5966
5976
  columns: exportColumns,
5967
5977
  source: source,
5968
- filename: "".concat(values.analyticsKey, "analytics").concat(comparisonMode ? "_comparison" : "").concat(filterSuffix ? "_".concat(filterSuffix) : "", "_").concat(source[0].startDate, "_").concat(source[0].endDate, ".csv")
5978
+ filename: "".concat(values.analyticsKey, "analytics_").concat(source[0].startDate, "_").concat(source[0].endDate, ".csv")
5969
5979
  });
5970
5980
  };
5971
5981
  return /*#__PURE__*/React__default["default"].createElement("div", {
@@ -5982,69 +5992,33 @@ const AnalyticsHub = _ref => {
5982
5992
  },
5983
5993
  isActive: isReadyToOpenCSV(),
5984
5994
  leftIcon: "file-code-o"
5985
- }, "Export CSV")), failedSites.length > 0 && /*#__PURE__*/React__default["default"].createElement(Components.Text, {
5986
- type: "help",
5987
- style: {
5988
- color: Colours.COLOUR_RED,
5989
- marginTop: 8
5990
- }
5991
- }, "Data unavailable for: ", failedSites.join(", ")), /*#__PURE__*/React__default["default"].createElement("div", {
5995
+ }, "Export CSV")), /*#__PURE__*/React__default["default"].createElement("div", {
5992
5996
  className: "analyticsSection dashboardSection_content"
5993
- }, (() => {
5994
- const chartSuffix = [selectedSites && selectedSites.length > 0 ? "&sites=".concat(selectedSites.join(",")) : "", userType ? "&userType=".concat(encodeURIComponent(userType)) : "", userCategory ? "&userCategory=".concat(encodeURIComponent(userCategory)) : ""].join("");
5995
- if (comparisonMode) {
5996
- return /*#__PURE__*/React__default["default"].createElement("div", {
5997
- style: {
5998
- display: "flex",
5999
- flexDirection: "column",
6000
- gap: 16
6001
- }
6002
- }, /*#__PURE__*/React__default["default"].createElement(Components.ComparisonStatBox, {
6003
- title: "".concat(featureTitle, " Requests"),
6004
- data: comparisonData.requests,
6005
- prevText: prevText,
6006
- viewGraphLink: "/chart?entity=".concat(values.analyticsKey, "&startTime=").concat(startTime, "&endTime=").concat(endTime, "&key=Request&countType=total&dayCount=").concat(dayCount).concat(chartSuffix),
6007
- isLoading: comparisonData.isLoading
6008
- }), /*#__PURE__*/React__default["default"].createElement(Components.ComparisonStatBox, {
6009
- title: "Completed ".concat(featureTitle, " Requests"),
6010
- data: comparisonData.completedRequests,
6011
- prevText: prevText,
6012
- viewGraphLink: "/chart?entity=".concat(values.analyticsKey, "&startTime=").concat(startTime, "&endTime=").concat(endTime, "&key=RequestCompleted&countType=unique&dayCount=").concat(dayCount).concat(chartSuffix),
6013
- isLoading: comparisonData.isLoading
6014
- }), /*#__PURE__*/React__default["default"].createElement(Components.ComparisonStatBox, {
6015
- title: "".concat(featureTitle, " Comments"),
6016
- data: comparisonData.comments,
6017
- prevText: prevText,
6018
- viewGraphLink: "/chart?entity=".concat(values.analyticsKey, "&startTime=").concat(startTime, "&endTime=").concat(endTime, "&key=Comment&countType=total&dayCount=").concat(dayCount).concat(chartSuffix),
6019
- isLoading: comparisonData.isLoading
6020
- }));
6021
- }
6022
- return /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, /*#__PURE__*/React__default["default"].createElement(Components.StatBox, {
6023
- title: "".concat(featureTitle, " Requests"),
6024
- icon: freeSolidSvgIcons.faWrench,
6025
- value: analyticsData.requests,
6026
- previousValue: analyticsData.prevRequests,
6027
- prevText: prevText,
6028
- viewGraphLink: "/chart?entity=".concat(values.analyticsKey, "&startTime=").concat(startTime, "&endTime=").concat(endTime, "&key=Request&countType=total&dayCount=").concat(dayCount).concat(chartSuffix),
6029
- isLoading: analyticsData.isLoading
6030
- }), /*#__PURE__*/React__default["default"].createElement(Components.StatBox, {
6031
- title: "Completed ".concat(featureTitle, " Requests"),
6032
- icon: freeSolidSvgIcons.faCircleCheck,
6033
- value: analyticsData.completedRequests,
6034
- previousValue: analyticsData.prevCompletedRequests,
6035
- prevText: prevText,
6036
- viewGraphLink: "/chart?entity=".concat(values.analyticsKey, "&startTime=").concat(startTime, "&endTime=").concat(endTime, "&key=RequestCompleted&countType=unique&dayCount=").concat(dayCount).concat(chartSuffix),
6037
- isLoading: analyticsData.isLoading
6038
- }), /*#__PURE__*/React__default["default"].createElement(Components.StatBox, {
6039
- title: "".concat(featureTitle, " Comments"),
6040
- icon: freeSolidSvgIcons.faComment,
6041
- value: analyticsData.comments,
6042
- previousValue: analyticsData.prevComments,
6043
- prevText: prevText,
6044
- viewGraphLink: "/chart?entity=".concat(values.analyticsKey, "&startTime=").concat(startTime, "&endTime=").concat(endTime, "&key=Comment&countType=total&dayCount=").concat(dayCount).concat(chartSuffix),
6045
- isLoading: analyticsData.isLoading
6046
- }));
6047
- })()));
5997
+ }, /*#__PURE__*/React__default["default"].createElement(Components.StatBox, {
5998
+ title: "".concat(featureTitle, " Requests"),
5999
+ icon: freeSolidSvgIcons.faWrench,
6000
+ value: analyticsData.requests,
6001
+ previousValue: analyticsData.prevRequests,
6002
+ prevText: prevText,
6003
+ viewGraphLink: "/chart?entity=".concat(values.analyticsKey, "&startTime=").concat(startTime, "&endTime=").concat(endTime, "&key=Request&countType=total&dayCount=").concat(dayCount),
6004
+ isLoading: analyticsData.isLoading
6005
+ }), /*#__PURE__*/React__default["default"].createElement(Components.StatBox, {
6006
+ title: "Completed ".concat(featureTitle, " Requests"),
6007
+ icon: freeSolidSvgIcons.faCircleCheck,
6008
+ value: analyticsData.completedRequests,
6009
+ previousValue: analyticsData.prevCompletedRequests,
6010
+ prevText: prevText,
6011
+ viewGraphLink: "/chart?entity=".concat(values.analyticsKey, "&startTime=").concat(startTime, "&endTime=").concat(endTime, "&key=RequestCompleted&countType=unique&dayCount=").concat(dayCount),
6012
+ isLoading: analyticsData.isLoading
6013
+ }), /*#__PURE__*/React__default["default"].createElement(Components.StatBox, {
6014
+ title: "".concat(featureTitle, " Comments"),
6015
+ icon: freeSolidSvgIcons.faComment,
6016
+ value: analyticsData.comments,
6017
+ previousValue: analyticsData.prevComments,
6018
+ prevText: prevText,
6019
+ viewGraphLink: "/chart?entity=".concat(values.analyticsKey, "&startTime=").concat(startTime, "&endTime=").concat(endTime, "&key=Comment&countType=total&dayCount=").concat(dayCount),
6020
+ isLoading: analyticsData.isLoading
6021
+ })));
6048
6022
  };
6049
6023
  const mapStateToProps = state => {
6050
6024
  const {