@plusscommunities/pluss-maintenance-web 1.1.16 → 1.1.18-beta.0
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.
- package/dist/index.cjs.js +4847 -14535
- package/dist/index.esm.js +4823 -14523
- package/dist/index.umd.js +4850 -14525
- package/package.json +7 -2
- package/src/actions/types.js +6 -4
- package/src/apis/maintenanceActions.js +34 -35
- package/src/components/ActivityText.js +12 -11
- package/src/components/AnalyticsHub.js +21 -12
- package/src/components/JobList.js +66 -24
- package/src/components/JobTypes.js +10 -162
- package/src/components/PreviewGrid.js +20 -7
- package/src/feature.config.js +41 -33
- package/src/index.js +15 -2
- package/src/screens/AddJob.js +482 -121
- package/src/screens/AddJobType.js +841 -0
- package/src/screens/Job.js +98 -40
- package/src/screens/RequestsHub.js +16 -8
- package/src/values.config.a.js +57 -0
- package/src/values.config.b.js +57 -0
- package/src/values.config.c.js +57 -0
- package/src/values.config.d.js +57 -0
- package/src/values.config.default.js +57 -0
- package/src/values.config.js +57 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plusscommunities/pluss-maintenance-web",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.18-beta.0",
|
|
4
4
|
"description": "Extension package to enable maintenance on Pluss Communities Platform",
|
|
5
5
|
"main": "dist/index.cjs.js",
|
|
6
6
|
"scripts": {
|
|
@@ -10,7 +10,12 @@
|
|
|
10
10
|
"betaupload": "npm run build && npm publish --access public --tag beta && rm -rf node_modules",
|
|
11
11
|
"betaupload:p": "npm run betapatch && npm run betaupload",
|
|
12
12
|
"upload": "npm run build && npm publish --access public && rm -rf node_modules",
|
|
13
|
-
"upload:p": "npm run patch && npm run upload"
|
|
13
|
+
"upload:p": "npm run patch && npm run upload",
|
|
14
|
+
"copy:add": "run(){ ext=${1:-default}; test -f src/values.config.$ext.js || cp src/values.config.default.js src/values.config.$ext.js; }; run",
|
|
15
|
+
"copy:get": "echo $npm_package_name",
|
|
16
|
+
"copy:set": "run(){ target='\\@plusscommunities\\/pluss-maintenance-web'; ext=${1:-default}; [ $ext == 'default' ] && replace=$target || replace=$target'-'$ext; echo 'Setting target to '$replace; test -f src/values.config.$ext.js && cp -f src/values.config.$ext.js src/values.config.js; sed -i '' -e 's/'$target'.*\"/'$replace'\"/g' package.json; }; run",
|
|
17
|
+
"copy:betaupload": "npm run betapatch; for file in `ls ./src/values.config.*.js`; do dup=`echo $file | sed 's/.*values\\.config\\.\\(.*\\)\\.js/\\1/'`; npm run copy:set $dup; npm run betaupload; done; npm run copy:set;",
|
|
18
|
+
"copy:upload": "npm run patch; for file in `ls ./src/values.config.*.js`; do dup=`echo $file | sed 's/.*values\\.config\\.\\(.*\\)\\.js/\\1/'`; npm run copy:set $dup; npm run upload; done; npm run copy:set;"
|
|
14
19
|
},
|
|
15
20
|
"author": "Phillip Suh",
|
|
16
21
|
"license": "ISC",
|
package/src/actions/types.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export const
|
|
4
|
-
export const
|
|
1
|
+
import { values } from '../values.config';
|
|
2
|
+
|
|
3
|
+
export const JOBS_LOADED = values.actionJobsLoaded;
|
|
4
|
+
export const JOBS_REMOVED = values.actionJobsRemoved;
|
|
5
|
+
export const JOBS_TYPES_LOADED = values.actionJobsTypesLoaded;
|
|
6
|
+
export const JOBS_LOADING = values.actionJobsLoading;
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
import { PlussCore } from '../feature.config';
|
|
2
|
+
import { values } from '../values.config';
|
|
2
3
|
const { Helper, Session } = PlussCore;
|
|
3
4
|
|
|
4
5
|
export const maintenanceActions = {
|
|
5
|
-
|
|
6
|
-
let url = Helper.getUrl(
|
|
6
|
+
getJobType: (site, typeId) => {
|
|
7
|
+
let url = Helper.getUrl(values.serviceKey, 'getjobtype');
|
|
8
|
+
return Session.authedFunction({
|
|
9
|
+
method: 'POST',
|
|
10
|
+
url,
|
|
11
|
+
data: { site, typeId },
|
|
12
|
+
});
|
|
13
|
+
},
|
|
14
|
+
getJobTypes: (site, id) => {
|
|
15
|
+
let url = Helper.getUrl(values.serviceKey, 'getjobtypes');
|
|
7
16
|
return Session.authedFunction({
|
|
8
17
|
method: 'POST',
|
|
9
18
|
url,
|
|
@@ -11,7 +20,7 @@ export const maintenanceActions = {
|
|
|
11
20
|
});
|
|
12
21
|
},
|
|
13
22
|
getJob: (site, id) => {
|
|
14
|
-
let url = Helper.getUrl(
|
|
23
|
+
let url = Helper.getUrl(values.serviceKey, 'getJob');
|
|
15
24
|
return Session.authedFunction({
|
|
16
25
|
method: 'POST',
|
|
17
26
|
url,
|
|
@@ -19,7 +28,7 @@ export const maintenanceActions = {
|
|
|
19
28
|
});
|
|
20
29
|
},
|
|
21
30
|
getJobByJobId: (site, jobId) => {
|
|
22
|
-
let url = Helper.getUrl(
|
|
31
|
+
let url = Helper.getUrl(values.serviceKey, 'getJob');
|
|
23
32
|
return Session.authedFunction({
|
|
24
33
|
method: 'POST',
|
|
25
34
|
url,
|
|
@@ -29,7 +38,7 @@ export const maintenanceActions = {
|
|
|
29
38
|
getJobs: (site, status = '', type = '') => {
|
|
30
39
|
return Session.authedFunction({
|
|
31
40
|
method: 'POST',
|
|
32
|
-
url: Helper.getUrl(
|
|
41
|
+
url: Helper.getUrl(values.serviceKey, 'getJobs'),
|
|
33
42
|
data: { site, status, type },
|
|
34
43
|
});
|
|
35
44
|
},
|
|
@@ -46,7 +55,7 @@ export const maintenanceActions = {
|
|
|
46
55
|
}
|
|
47
56
|
return Session.authedFunction({
|
|
48
57
|
method: 'GET',
|
|
49
|
-
url: Helper.getUrl(
|
|
58
|
+
url: Helper.getUrl(values.serviceKey, 'get/requests', query),
|
|
50
59
|
});
|
|
51
60
|
},
|
|
52
61
|
getJobsRecursive: (site, status, type, lastKey, jobs = []) => {
|
|
@@ -63,7 +72,7 @@ export const maintenanceActions = {
|
|
|
63
72
|
createJob: (job) => {
|
|
64
73
|
return Session.authedFunction({
|
|
65
74
|
method: 'POST',
|
|
66
|
-
url: Helper.getUrl(
|
|
75
|
+
url: Helper.getUrl(values.serviceKey, 'sendMaintenance'),
|
|
67
76
|
data: {
|
|
68
77
|
...job,
|
|
69
78
|
},
|
|
@@ -72,28 +81,28 @@ export const maintenanceActions = {
|
|
|
72
81
|
editJob: (job, site) => {
|
|
73
82
|
return Session.authedFunction({
|
|
74
83
|
method: 'POST',
|
|
75
|
-
url: Helper.getUrl(
|
|
84
|
+
url: Helper.getUrl(values.serviceKey, 'editJob'),
|
|
76
85
|
data: { job, site },
|
|
77
86
|
});
|
|
78
87
|
},
|
|
79
88
|
deleteJob: (site, id) => {
|
|
80
89
|
return Session.authedFunction({
|
|
81
90
|
method: 'POST',
|
|
82
|
-
url: Helper.getUrl(
|
|
91
|
+
url: Helper.getUrl(values.serviceKey, 'requests/remove'),
|
|
83
92
|
data: { site, id },
|
|
84
93
|
});
|
|
85
94
|
},
|
|
86
95
|
editJobStatus: (id, status) => {
|
|
87
96
|
return Session.authedFunction({
|
|
88
97
|
method: 'POST',
|
|
89
|
-
url: Helper.getUrl(
|
|
98
|
+
url: Helper.getUrl(values.serviceKey, 'editJobStatus'),
|
|
90
99
|
data: { id, status },
|
|
91
100
|
});
|
|
92
101
|
},
|
|
93
102
|
assignJob: (jobId, userId) => {
|
|
94
103
|
return Session.authedFunction({
|
|
95
104
|
method: 'POST',
|
|
96
|
-
url: Helper.getUrl(
|
|
105
|
+
url: Helper.getUrl(values.serviceKey, 'update/assign'),
|
|
97
106
|
data: {
|
|
98
107
|
id: jobId,
|
|
99
108
|
userId,
|
|
@@ -103,13 +112,13 @@ export const maintenanceActions = {
|
|
|
103
112
|
getAssignees: (site) => {
|
|
104
113
|
return Session.authedFunction({
|
|
105
114
|
method: 'GET',
|
|
106
|
-
url: Helper.getUrl(
|
|
115
|
+
url: Helper.getUrl(values.serviceKey, 'get/assignees', { site }),
|
|
107
116
|
});
|
|
108
117
|
},
|
|
109
118
|
addNote: (jobId, note, attachments) => {
|
|
110
119
|
return Session.authedFunction({
|
|
111
120
|
method: 'POST',
|
|
112
|
-
url: Helper.getUrl(
|
|
121
|
+
url: Helper.getUrl(values.serviceKey, 'requests/note'),
|
|
113
122
|
data: {
|
|
114
123
|
id: jobId,
|
|
115
124
|
note,
|
|
@@ -121,7 +130,7 @@ export const maintenanceActions = {
|
|
|
121
130
|
editNote: (jobId, noteId, note, attachments) => {
|
|
122
131
|
return Session.authedFunction({
|
|
123
132
|
method: 'POST',
|
|
124
|
-
url: Helper.getUrl(
|
|
133
|
+
url: Helper.getUrl(values.serviceKey, 'requests/note'),
|
|
125
134
|
data: {
|
|
126
135
|
id: jobId,
|
|
127
136
|
note,
|
|
@@ -134,7 +143,7 @@ export const maintenanceActions = {
|
|
|
134
143
|
deleteNote: (jobId, noteId) => {
|
|
135
144
|
return Session.authedFunction({
|
|
136
145
|
method: 'POST',
|
|
137
|
-
url: Helper.getUrl(
|
|
146
|
+
url: Helper.getUrl(values.serviceKey, 'requests/note'),
|
|
138
147
|
data: {
|
|
139
148
|
id: jobId,
|
|
140
149
|
noteId,
|
|
@@ -142,37 +151,27 @@ export const maintenanceActions = {
|
|
|
142
151
|
},
|
|
143
152
|
});
|
|
144
153
|
},
|
|
145
|
-
addJobType: (site, name, email, description, level) => {
|
|
154
|
+
addJobType: (site, name, email, description, level, hasCustomFields, customFields) => {
|
|
155
|
+
const data = { site, name, email, description, level, hasCustomFields, customFields: customFields || [] };
|
|
146
156
|
return Session.authedFunction({
|
|
147
157
|
method: 'POST',
|
|
148
|
-
url: Helper.getUrl(
|
|
149
|
-
data
|
|
150
|
-
site,
|
|
151
|
-
name,
|
|
152
|
-
email,
|
|
153
|
-
description,
|
|
154
|
-
level,
|
|
155
|
-
},
|
|
158
|
+
url: Helper.getUrl(values.serviceKey, 'createJobType'),
|
|
159
|
+
data,
|
|
156
160
|
});
|
|
157
161
|
},
|
|
158
|
-
editJobType: (site, id, name, email, description, level) => {
|
|
162
|
+
editJobType: (site, id, name, email, description, level, hasCustomFields, customFields) => {
|
|
163
|
+
const data = { site, id, name, email, description, level, hasCustomFields, customFields: customFields || [] };
|
|
164
|
+
if (hasCustomFields && customFields) data.customFields = customFields;
|
|
159
165
|
return Session.authedFunction({
|
|
160
166
|
method: 'POST',
|
|
161
|
-
url: Helper.getUrl(
|
|
162
|
-
data
|
|
163
|
-
site,
|
|
164
|
-
id,
|
|
165
|
-
name,
|
|
166
|
-
email,
|
|
167
|
-
description,
|
|
168
|
-
level,
|
|
169
|
-
},
|
|
167
|
+
url: Helper.getUrl(values.serviceKey, 'editJobType'),
|
|
168
|
+
data,
|
|
170
169
|
});
|
|
171
170
|
},
|
|
172
171
|
deleteJobType: (site, id) => {
|
|
173
172
|
return Session.authedFunction({
|
|
174
173
|
method: 'POST',
|
|
175
|
-
url: Helper.getUrl(
|
|
174
|
+
url: Helper.getUrl(values.serviceKey, 'deleteJobType'),
|
|
176
175
|
data: {
|
|
177
176
|
site,
|
|
178
177
|
id,
|
|
@@ -1,47 +1,48 @@
|
|
|
1
1
|
import React, { Component } from 'react';
|
|
2
2
|
import _ from 'lodash';
|
|
3
3
|
import { Link } from 'react-router-dom';
|
|
4
|
+
import { values } from '../values.config';
|
|
4
5
|
|
|
5
6
|
class ActivityText extends Component {
|
|
6
7
|
render() {
|
|
7
8
|
const { data, classes, clickableClasses, highlightedClasses } = this.props;
|
|
8
9
|
|
|
9
10
|
switch (data.Type) {
|
|
10
|
-
case
|
|
11
|
+
case values.activityMaintenanceJobStatusChanged:
|
|
11
12
|
return (
|
|
12
13
|
<p className={classes}>
|
|
13
14
|
<span className={highlightedClasses}>{data.User.displayName}</span>
|
|
14
|
-
|
|
15
|
-
<Link to={
|
|
15
|
+
{values.textChangedRequestStatus}
|
|
16
|
+
<Link to={`${values.routeRequestDetails}/${data.Id}`} className={clickableClasses}>
|
|
16
17
|
{_.truncate(data.Data.title || data.Data.description, { length: 30, separator: '...' })}
|
|
17
18
|
</Link>
|
|
18
19
|
</p>
|
|
19
20
|
);
|
|
20
|
-
case
|
|
21
|
+
case values.activityAddMaintenanceJob:
|
|
21
22
|
return (
|
|
22
23
|
<p className={classes}>
|
|
23
24
|
<span className={highlightedClasses}>{data.User.displayName}</span>
|
|
24
|
-
|
|
25
|
-
<Link to={
|
|
25
|
+
{values.textAddedRequest}
|
|
26
|
+
<Link to={`${values.routeRequestDetails}/${data.Id}`} className={clickableClasses}>
|
|
26
27
|
{_.truncate(data.Data.title || data.Data.description, { length: 30, separator: '...' })}
|
|
27
28
|
</Link>
|
|
28
29
|
</p>
|
|
29
30
|
);
|
|
30
|
-
case
|
|
31
|
+
case values.activityEditMaintenanceJob:
|
|
31
32
|
return (
|
|
32
33
|
<p className={classes}>
|
|
33
34
|
<span className={highlightedClasses}>{data.User.displayName}</span>
|
|
34
|
-
|
|
35
|
-
<Link to={
|
|
35
|
+
{values.textEditedRequest}
|
|
36
|
+
<Link to={`${values.routeRequestDetails}/${data.Id}`} className={clickableClasses}>
|
|
36
37
|
{_.truncate(data.Data.title || data.Data.description, { length: 30, separator: '...' })}
|
|
37
38
|
</Link>
|
|
38
39
|
</p>
|
|
39
40
|
);
|
|
40
|
-
case
|
|
41
|
+
case values.activityDeleteMaintenanceJob:
|
|
41
42
|
return (
|
|
42
43
|
<p className={classes}>
|
|
43
44
|
<span className={highlightedClasses}>{data.User.displayName}</span>
|
|
44
|
-
|
|
45
|
+
{values.textRemovedRequest}
|
|
45
46
|
<span className={highlightedClasses}>
|
|
46
47
|
{_.truncate(data.Data.title || data.Data.description, { length: 30, separator: '...' })}
|
|
47
48
|
</span>
|
|
@@ -4,6 +4,7 @@ import { faCircleCheck, faComment, faWrench } from '@fortawesome/free-solid-svg-
|
|
|
4
4
|
import { connect } from 'react-redux';
|
|
5
5
|
import { analyticsActions } from '../apis';
|
|
6
6
|
import { PlussCore } from '../feature.config';
|
|
7
|
+
import { values } from '../values.config';
|
|
7
8
|
|
|
8
9
|
const { Analytics, Session, Components } = PlussCore;
|
|
9
10
|
|
|
@@ -18,15 +19,22 @@ const getInitialState = () => ({
|
|
|
18
19
|
});
|
|
19
20
|
|
|
20
21
|
// AnalyticsHub Component
|
|
21
|
-
const AnalyticsHub = ({ startTime, endTime, auth, prevText, dayCount }) => {
|
|
22
|
+
const AnalyticsHub = ({ startTime, endTime, auth, prevText, dayCount, strings }) => {
|
|
22
23
|
const [analyticsData, setAnalyticsData] = useState(getInitialState());
|
|
23
24
|
const [isExportOpen, setIsExportOpen] = useState(false);
|
|
24
25
|
|
|
25
|
-
const hasAccess = Session.validateAccess(auth.site,
|
|
26
|
+
const hasAccess = Session.validateAccess(auth.site, values.permissionMaintenanceTracking, auth);
|
|
26
27
|
if (!hasAccess) {
|
|
27
28
|
return null;
|
|
28
29
|
}
|
|
29
30
|
|
|
31
|
+
const featureTitle = ((key) => {
|
|
32
|
+
if (!strings || !strings.sideNav || !strings.sideNav[key]) {
|
|
33
|
+
return values.textMenuTitle;
|
|
34
|
+
}
|
|
35
|
+
return strings.sideNav[key];
|
|
36
|
+
})();
|
|
37
|
+
|
|
30
38
|
const exportColumns = [
|
|
31
39
|
{ label: 'Select All', key: '' },
|
|
32
40
|
{ label: 'Start Date', key: 'startDate' },
|
|
@@ -45,8 +53,8 @@ const AnalyticsHub = ({ startTime, endTime, auth, prevText, dayCount }) => {
|
|
|
45
53
|
// Load analytics data here using startTime and endTime
|
|
46
54
|
const timeDifference = endTime - startTime;
|
|
47
55
|
const [currentStatsResponse, prevStatsResponse] = await Promise.all([
|
|
48
|
-
analyticsActions.getAggregateEntityStats(auth.site,
|
|
49
|
-
analyticsActions.getAggregateEntityStats(auth.site,
|
|
56
|
+
analyticsActions.getAggregateEntityStats(auth.site, values.analyticsKey, startTime, endTime, true),
|
|
57
|
+
analyticsActions.getAggregateEntityStats(auth.site, values.analyticsKey, startTime - timeDifference, startTime, true),
|
|
50
58
|
]);
|
|
51
59
|
|
|
52
60
|
const data = {
|
|
@@ -89,7 +97,7 @@ const AnalyticsHub = ({ startTime, endTime, auth, prevText, dayCount }) => {
|
|
|
89
97
|
}}
|
|
90
98
|
columns={exportColumns}
|
|
91
99
|
source={source}
|
|
92
|
-
filename={
|
|
100
|
+
filename={`${values.analyticsKey}analytics_${source[0].startDate}_${source[0].endDate}.csv`}
|
|
93
101
|
/>
|
|
94
102
|
);
|
|
95
103
|
};
|
|
@@ -99,7 +107,7 @@ const AnalyticsHub = ({ startTime, endTime, auth, prevText, dayCount }) => {
|
|
|
99
107
|
{csvPopup()}
|
|
100
108
|
<div>
|
|
101
109
|
<Components.Text type="h4" className="inlineBlock marginRight-40">
|
|
102
|
-
|
|
110
|
+
{featureTitle}
|
|
103
111
|
</Components.Text>
|
|
104
112
|
<Components.Button
|
|
105
113
|
inline
|
|
@@ -116,30 +124,30 @@ const AnalyticsHub = ({ startTime, endTime, auth, prevText, dayCount }) => {
|
|
|
116
124
|
</div>
|
|
117
125
|
<div className="analyticsSection dashboardSection_content">
|
|
118
126
|
<Components.StatBox
|
|
119
|
-
title=
|
|
127
|
+
title={`${featureTitle} Requests`}
|
|
120
128
|
icon={faWrench}
|
|
121
129
|
value={analyticsData.requests}
|
|
122
130
|
previousValue={analyticsData.prevRequests}
|
|
123
131
|
prevText={prevText}
|
|
124
|
-
viewGraphLink={`/chart?entity
|
|
132
|
+
viewGraphLink={`/chart?entity=${values.analyticsKey}&startTime=${startTime}&endTime=${endTime}&key=Request&countType=total&dayCount=${dayCount}`}
|
|
125
133
|
isLoading={analyticsData.isLoading}
|
|
126
134
|
/>
|
|
127
135
|
<Components.StatBox
|
|
128
|
-
title=
|
|
136
|
+
title={`Completed ${featureTitle} Requests`}
|
|
129
137
|
icon={faCircleCheck}
|
|
130
138
|
value={analyticsData.completedRequests}
|
|
131
139
|
previousValue={analyticsData.prevCompletedRequests}
|
|
132
140
|
prevText={prevText}
|
|
133
|
-
viewGraphLink={`/chart?entity
|
|
141
|
+
viewGraphLink={`/chart?entity=${values.analyticsKey}&startTime=${startTime}&endTime=${endTime}&key=RequestCompleted&countType=unique&dayCount=${dayCount}`}
|
|
134
142
|
isLoading={analyticsData.isLoading}
|
|
135
143
|
/>
|
|
136
144
|
<Components.StatBox
|
|
137
|
-
title=
|
|
145
|
+
title={`${featureTitle} Comments`}
|
|
138
146
|
icon={faComment}
|
|
139
147
|
value={analyticsData.comments}
|
|
140
148
|
previousValue={analyticsData.prevComments}
|
|
141
149
|
prevText={prevText}
|
|
142
|
-
viewGraphLink={`/chart?entity
|
|
150
|
+
viewGraphLink={`/chart?entity=${values.analyticsKey}&startTime=${startTime}&endTime=${endTime}&key=Comment&countType=total&dayCount=${dayCount}`}
|
|
143
151
|
isLoading={analyticsData.isLoading}
|
|
144
152
|
/>
|
|
145
153
|
</div>
|
|
@@ -151,6 +159,7 @@ const mapStateToProps = (state) => {
|
|
|
151
159
|
const { auth } = state;
|
|
152
160
|
return {
|
|
153
161
|
auth,
|
|
162
|
+
strings: (state.strings && state.strings.config) || {},
|
|
154
163
|
};
|
|
155
164
|
};
|
|
156
165
|
|
|
@@ -11,6 +11,7 @@ import { PlussCore } from '../feature.config';
|
|
|
11
11
|
import { maintenanceActions } from '../apis';
|
|
12
12
|
import StatusTypes from '../maintenanceStatus.json';
|
|
13
13
|
import { Colours } from '@plusscommunities/pluss-core-web';
|
|
14
|
+
import { values } from '../values.config';
|
|
14
15
|
|
|
15
16
|
const { Session, Components, Analytics } = PlussCore;
|
|
16
17
|
|
|
@@ -28,11 +29,11 @@ class JobList extends Component {
|
|
|
28
29
|
this.exportColumns = [
|
|
29
30
|
{ label: 'Select All', key: '' },
|
|
30
31
|
{ label: 'System Id', key: 'id' },
|
|
31
|
-
{ label:
|
|
32
|
+
{ label: `${values.textEntityName} No.`, key: 'jobId' },
|
|
32
33
|
{ label: 'Type', key: 'type' },
|
|
33
34
|
{ label: 'Status', key: 'status' },
|
|
34
35
|
{ label: 'Title', key: 'title' },
|
|
35
|
-
{ label: '
|
|
36
|
+
{ label: 'Address', key: 'room' },
|
|
36
37
|
{ label: 'Description', key: 'description' },
|
|
37
38
|
{ label: 'Notes', key: 'notes' },
|
|
38
39
|
{ label: 'User Name', key: 'userName' },
|
|
@@ -85,7 +86,7 @@ class JobList extends Component {
|
|
|
85
86
|
};
|
|
86
87
|
|
|
87
88
|
onRemoveRequest = async (request) => {
|
|
88
|
-
if (window.confirm(
|
|
89
|
+
if (window.confirm(values.textAreYouSureYouWantToDelete)) {
|
|
89
90
|
this.props.removeJob(request.id);
|
|
90
91
|
try {
|
|
91
92
|
await maintenanceActions.deleteJob(this.props.auth.site, request.id);
|
|
@@ -274,8 +275,45 @@ class JobList extends Component {
|
|
|
274
275
|
return source;
|
|
275
276
|
};
|
|
276
277
|
|
|
278
|
+
getCustomFieldValue = (field) => {
|
|
279
|
+
switch (field.type) {
|
|
280
|
+
case 'date':
|
|
281
|
+
return field.answer ? moment(field.answer, 'YYYY-MM-DD').format('DD-MMM-YYYY') : '';
|
|
282
|
+
case 'time':
|
|
283
|
+
return field.answer ? moment(field.answer, 'HH:mm').format('h:mm a') : '';
|
|
284
|
+
case 'yn':
|
|
285
|
+
return field.answer ? 'Yes' : 'No';
|
|
286
|
+
case 'checkbox':
|
|
287
|
+
return field.answer && Array.isArray(field.answer) ? field.answer.join(', ') : '';
|
|
288
|
+
default:
|
|
289
|
+
return field.answer;
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
getCustomFields = (job, customColumns) => {
|
|
294
|
+
const { customFields, type } = job;
|
|
295
|
+
const customValues = {};
|
|
296
|
+
if (customFields && Array.isArray(customFields)) {
|
|
297
|
+
customFields.forEach((field) => {
|
|
298
|
+
// Exclude un-exportable fields
|
|
299
|
+
if (['image', 'staticTitle', 'staticText'].includes(field.type)) return;
|
|
300
|
+
|
|
301
|
+
const fieldKey = `${_.camelCase(type)}.${_.camelCase(field.label)}`;
|
|
302
|
+
// Build custom columns
|
|
303
|
+
const exists = customColumns.find((c) => c.key === fieldKey);
|
|
304
|
+
if (!exists) {
|
|
305
|
+
customColumns.push({ label: field.label, key: fieldKey });
|
|
306
|
+
}
|
|
307
|
+
// Build custom field source
|
|
308
|
+
customValues[fieldKey] = this.getCustomFieldValue(field);
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
return customValues;
|
|
312
|
+
};
|
|
313
|
+
|
|
277
314
|
getExportSource = () => {
|
|
278
|
-
|
|
315
|
+
const customColumns = [];
|
|
316
|
+
const source = this.getSource().map((r) => {
|
|
279
317
|
const history = r.history || [];
|
|
280
318
|
const progressEntry = _.find(history, (e) => {
|
|
281
319
|
return e.status !== 'Unassigned';
|
|
@@ -308,8 +346,14 @@ class JobList extends Component {
|
|
|
308
346
|
}
|
|
309
347
|
notes += note.Note;
|
|
310
348
|
});
|
|
311
|
-
|
|
349
|
+
const customFieldValues = this.getCustomFields(r, customColumns);
|
|
350
|
+
return { ...r, ...customFieldValues, notes, progressTime, completedTime, progressDuration, completedDuration };
|
|
312
351
|
});
|
|
352
|
+
|
|
353
|
+
// Compose revised columns list with custom fields
|
|
354
|
+
const index = this.exportColumns.findIndex((c) => c.key === 'notes');
|
|
355
|
+
const columns = [...this.exportColumns.slice(0, index), ...customColumns, ...this.exportColumns.slice(index)];
|
|
356
|
+
return { columns, source };
|
|
313
357
|
};
|
|
314
358
|
|
|
315
359
|
isExportReady = () => {
|
|
@@ -335,6 +379,7 @@ class JobList extends Component {
|
|
|
335
379
|
{_.sortBy(_.uniq(this.props.source.map((r) => r.type)), (t) => t.toLowerCase()).map((type) => {
|
|
336
380
|
return (
|
|
337
381
|
<Components.Tag
|
|
382
|
+
key={type}
|
|
338
383
|
onClick={() => {
|
|
339
384
|
this.selectTypeFilter(type);
|
|
340
385
|
}}
|
|
@@ -353,6 +398,7 @@ class JobList extends Component {
|
|
|
353
398
|
const text = sKey === 'incomplete' ? 'All Incomplete' : StatusTypes[sKey].text;
|
|
354
399
|
return (
|
|
355
400
|
<Components.Tag
|
|
401
|
+
key={sKey}
|
|
356
402
|
onClick={() => {
|
|
357
403
|
this.selectStatusFilter(sKey);
|
|
358
404
|
}}
|
|
@@ -476,7 +522,7 @@ class JobList extends Component {
|
|
|
476
522
|
<tr key={index}>
|
|
477
523
|
<td>{ev.jobId}</td>
|
|
478
524
|
<td className="table-TitleColumn">
|
|
479
|
-
<Link to={
|
|
525
|
+
<Link to={`${values.routeRequestDetails}/${ev.id}`}>
|
|
480
526
|
<span>{ev.title}</span>
|
|
481
527
|
</Link>
|
|
482
528
|
</td>
|
|
@@ -504,10 +550,10 @@ class JobList extends Component {
|
|
|
504
550
|
</td>
|
|
505
551
|
<td className="table-options">
|
|
506
552
|
<div style={{ display: 'flex', alignItems: 'center' }}>
|
|
507
|
-
<Link to={
|
|
553
|
+
<Link to={`${values.routeRequestDetails}/${ev.id}`}>
|
|
508
554
|
<FontAwesome style={{ fontSize: 20, padding: 5, cursor: 'pointer' }} name="pencil" />
|
|
509
555
|
</Link>
|
|
510
|
-
{Session.validateAccess(this.props.auth.site,
|
|
556
|
+
{Session.validateAccess(this.props.auth.site, values.permissionMaintenanceTracking, this.props.auth) && (
|
|
511
557
|
<a onClick={() => this.onRemoveRequest(ev)}>
|
|
512
558
|
<FontAwesome style={{ fontSize: 20, padding: 5, marginLeft: 8, cursor: 'pointer' }} name="minus-circle" />
|
|
513
559
|
</a>
|
|
@@ -531,17 +577,19 @@ class JobList extends Component {
|
|
|
531
577
|
}
|
|
532
578
|
|
|
533
579
|
renderEmpty() {
|
|
580
|
+
const title = this.props.strings[`${values.featureKey}_textTitleRequests`] || values.textTitleRequests;
|
|
581
|
+
|
|
534
582
|
return (
|
|
535
583
|
<div style={{ display: 'flex', flexDirection: 'column', flex: 1, justifyContent: 'center', alignItems: 'center', marginTop: 32 }}>
|
|
536
584
|
<div className="emptyState" />
|
|
537
585
|
<div className="marginTop-32" style={{ maxWidth: 500, textAlign: 'center' }}>
|
|
538
586
|
<span className="fontRegular fontSize-13">
|
|
539
|
-
<span className="fontHeavy text-brandingColour">
|
|
540
|
-
|
|
587
|
+
<span className="fontHeavy text-brandingColour">{title} </span>
|
|
588
|
+
{values.textEmptyDescription}
|
|
541
589
|
</span>
|
|
542
590
|
</div>
|
|
543
591
|
<div className="marginTop-8 fontRegular fontSize-13" style={{ maxWidth: 500, textAlign: 'center' }}>
|
|
544
|
-
|
|
592
|
+
{values.textEmptyExample}
|
|
545
593
|
</div>
|
|
546
594
|
</div>
|
|
547
595
|
);
|
|
@@ -561,7 +609,7 @@ class JobList extends Component {
|
|
|
561
609
|
this.sortByCol('jobId');
|
|
562
610
|
}}
|
|
563
611
|
>
|
|
564
|
-
|
|
612
|
+
{values.textEntityName} No.{this.renderSort('jobId')}
|
|
565
613
|
</th>
|
|
566
614
|
<th
|
|
567
615
|
className={`${this.sortIsActive('title')}`}
|
|
@@ -597,7 +645,7 @@ class JobList extends Component {
|
|
|
597
645
|
this.sortByCol('room');
|
|
598
646
|
}}
|
|
599
647
|
>
|
|
600
|
-
|
|
648
|
+
Address{this.renderSort('room')}
|
|
601
649
|
</th>
|
|
602
650
|
<th
|
|
603
651
|
className={`${this.sortIsActive('assigned')}`}
|
|
@@ -745,7 +793,7 @@ class JobList extends Component {
|
|
|
745
793
|
<Components.GenericInput
|
|
746
794
|
id="search"
|
|
747
795
|
type="text"
|
|
748
|
-
placeholder=
|
|
796
|
+
placeholder={`Search by ${values.textEntityName} ID, Address or Title`}
|
|
749
797
|
value={this.state.search}
|
|
750
798
|
onChange={(e) => this.onHandleSearchChange(e)}
|
|
751
799
|
className="genericInputContainer-rounded marginTop-10"
|
|
@@ -760,14 +808,8 @@ class JobList extends Component {
|
|
|
760
808
|
return null;
|
|
761
809
|
}
|
|
762
810
|
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
onClose={this.onCloseExportCsv}
|
|
766
|
-
columns={this.exportColumns}
|
|
767
|
-
source={this.getExportSource()}
|
|
768
|
-
filename="requests.csv"
|
|
769
|
-
/>
|
|
770
|
-
);
|
|
811
|
+
const { columns, source } = this.getExportSource();
|
|
812
|
+
return <Components.ExportCsvPopup onClose={this.onCloseExportCsv} columns={columns} source={source} filename="requests.csv" />;
|
|
771
813
|
}
|
|
772
814
|
|
|
773
815
|
render() {
|
|
@@ -783,11 +825,11 @@ class JobList extends Component {
|
|
|
783
825
|
}
|
|
784
826
|
|
|
785
827
|
const mapStateToProps = (state) => {
|
|
786
|
-
const { jobs } = state.maintenance;
|
|
787
828
|
const { auth } = state;
|
|
788
829
|
return {
|
|
789
|
-
jobs,
|
|
830
|
+
jobs: state[values.reducerKey].jobs,
|
|
790
831
|
auth,
|
|
832
|
+
strings: (state.strings && state.strings.config) || {},
|
|
791
833
|
};
|
|
792
834
|
};
|
|
793
835
|
|