@spokane-folio/security-incident 1.0.28
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/.eslintrc +32 -0
- package/.github/workflows/CODEOWNERS +8 -0
- package/.github/workflows/pr-validation.yml +44 -0
- package/.github/workflows/release.yml +64 -0
- package/.prettierrc +6 -0
- package/.stripesclirc +4 -0
- package/CHANGELOG.md +8 -0
- package/CONTRIBUTING.md +4 -0
- package/LICENSE +201 -0
- package/README.md +16 -0
- package/administrator-documentation/roles-and-permissions.md +65 -0
- package/administrator-documentation/track-settings-admin-guide-sketch.md +192 -0
- package/administrator-documentation/using-the-application.md +192 -0
- package/icons/app.png +0 -0
- package/icons/app.svg +1 -0
- package/icons/playButton.png +0 -0
- package/icons/profilePicThumbnail.png +0 -0
- package/jest.config.js +10 -0
- package/module-descriptor.json +75 -0
- package/output/service-worker.js +0 -0
- package/package.json +146 -0
- package/src/components/incidents/ColumnChooser.js +37 -0
- package/src/components/incidents/CreateMedia.js +132 -0
- package/src/components/incidents/CreatePane.js +1215 -0
- package/src/components/incidents/CreatePane.test.js +138 -0
- package/src/components/incidents/CreateReport.js +102 -0
- package/src/components/incidents/DetailsPane.js +1267 -0
- package/src/components/incidents/DetailsPane.test.js +150 -0
- package/src/components/incidents/EditPane.js +2334 -0
- package/src/components/incidents/EditPane.test.js +187 -0
- package/src/components/incidents/GetDetails.js +55 -0
- package/src/components/incidents/GetListDQLinkIncident.js +81 -0
- package/src/components/incidents/GetListDynamicQuery.js +66 -0
- package/src/components/incidents/GetLocations.js +57 -0
- package/src/components/incidents/GetMedia.js +98 -0
- package/src/components/incidents/GetName.js +111 -0
- package/src/components/incidents/GetNameCreatedBy.js +94 -0
- package/src/components/incidents/GetOrgLocaleSettings.js +61 -0
- package/src/components/incidents/GetPatronGroups.js +52 -0
- package/src/components/incidents/GetSelf.js +65 -0
- package/src/components/incidents/GetSummary.js +110 -0
- package/src/components/incidents/IncidentTypeCard.js +53 -0
- package/src/components/incidents/IncidentTypeCard.test.js +133 -0
- package/src/components/incidents/IncidentsPaneset.js +810 -0
- package/src/components/incidents/IncidentsPaneset.test.js +128 -0
- package/src/components/incidents/LinkedIncident.js +86 -0
- package/src/components/incidents/ModalAddMedia.js +262 -0
- package/src/components/incidents/ModalAddMedia.test.js +97 -0
- package/src/components/incidents/ModalAttentionDecOfService.js +111 -0
- package/src/components/incidents/ModalCustomWitness.js +469 -0
- package/src/components/incidents/ModalCustomWitness.test.js +147 -0
- package/src/components/incidents/ModalCustomerDetails.js +480 -0
- package/src/components/incidents/ModalCustomerDetails.test.js +116 -0
- package/src/components/incidents/ModalDescribeCustomer.js +361 -0
- package/src/components/incidents/ModalDescribeCustomer.test.js +156 -0
- package/src/components/incidents/ModalDirtyFormWarn.js +62 -0
- package/src/components/incidents/ModalLinkIncident.js +1213 -0
- package/src/components/incidents/ModalLinkIncidentStyle.css +32 -0
- package/src/components/incidents/ModalSelectIncidentTypes.js +178 -0
- package/src/components/incidents/ModalSelectIncidentTypes.test.js +273 -0
- package/src/components/incidents/ModalSelectKnownCustomer.js +395 -0
- package/src/components/incidents/ModalSelectWitness.js +406 -0
- package/src/components/incidents/ModalSelectWitness.test.js +308 -0
- package/src/components/incidents/ModalStyle.css +44 -0
- package/src/components/incidents/ModalTrespass.js +741 -0
- package/src/components/incidents/ModalViewCustomerDetails.js +241 -0
- package/src/components/incidents/ModalViewMedia.js +86 -0
- package/src/components/incidents/ModalViewTrespass.js +210 -0
- package/src/components/incidents/ResultsPane.js +437 -0
- package/src/components/incidents/ResultsPane.test.js +120 -0
- package/src/components/incidents/SearchCustomerOrWitness.js +108 -0
- package/src/components/incidents/Thumbnail.js +72 -0
- package/src/components/incidents/ThumbnailMarkRemoval.js +38 -0
- package/src/components/incidents/ThumbnailSkeleton.js +30 -0
- package/src/components/incidents/ThumbnailStyles.js +49 -0
- package/src/components/incidents/ThumbnailTempPreSave.js +71 -0
- package/src/components/incidents/UpdateReport.js +84 -0
- package/src/components/incidents/__snapshots__/CreatePane.test.js.snap +3 -0
- package/src/components/incidents/__snapshots__/DetailsPane.test.js.snap +3 -0
- package/src/components/incidents/__snapshots__/EditPane.test.js.snap +3 -0
- package/src/components/incidents/__snapshots__/IncidentTypeCard.test.js.snap +3 -0
- package/src/components/incidents/__snapshots__/IncidentsPaneset.test.js.snap +3 -0
- package/src/components/incidents/__snapshots__/ModalAddMedia.test.js.snap +3 -0
- package/src/components/incidents/__snapshots__/ModalCustomerDetails.test.js.snap +3 -0
- package/src/components/incidents/__snapshots__/ModalSelectWitness.test.js.snap +3 -0
- package/src/components/incidents/__snapshots__/ResultsPane.test.js.snap +3 -0
- package/src/components/incidents/helpers/ProfilePicture/ProfilePicture.css +5 -0
- package/src/components/incidents/helpers/ProfilePicture/ProfilePicture.js +51 -0
- package/src/components/incidents/helpers/ProfilePicture/isAValidURL.js +3 -0
- package/src/components/incidents/helpers/ProfilePicture/useProfilePicture.js +127 -0
- package/src/components/incidents/helpers/buildQueryString.js +28 -0
- package/src/components/incidents/helpers/cleanFormValues.js +53 -0
- package/src/components/incidents/helpers/computeEditedCustomers.js +124 -0
- package/src/components/incidents/helpers/convertDateIgnoringTZ.js +8 -0
- package/src/components/incidents/helpers/convertUTCISOToLocalePrettyTime.js +15 -0
- package/src/components/incidents/helpers/convertUTCISOToPrettyDate.js +19 -0
- package/src/components/incidents/helpers/decodeParamsToForm.js +20 -0
- package/src/components/incidents/helpers/deepNormalizeForComparison.js +39 -0
- package/src/components/incidents/helpers/extractFilterString.js +12 -0
- package/src/components/incidents/helpers/formatDateAndTimeToUTCISO.js +14 -0
- package/src/components/incidents/helpers/formatDateToUTCISO.js +14 -0
- package/src/components/incidents/helpers/formatTimeToUTCISO.js +28 -0
- package/src/components/incidents/helpers/getCurrentTime.js +20 -0
- package/src/components/incidents/helpers/getTodayDate.js +12 -0
- package/src/components/incidents/helpers/handlebarsHelpers.js +148 -0
- package/src/components/incidents/helpers/hasFormChangedAtCreate.js +50 -0
- package/src/components/incidents/helpers/hasTopLevelChangeAffectedDeclaration.js +90 -0
- package/src/components/incidents/helpers/hasTopLevelFormChanged.js +111 -0
- package/src/components/incidents/helpers/identifyCurrentTrespassDocs.js +109 -0
- package/src/components/incidents/helpers/isSameHtml.js +13 -0
- package/src/components/incidents/helpers/isValidDateFormat.js +14 -0
- package/src/components/incidents/helpers/isValidTimeInput.js +11 -0
- package/src/components/incidents/helpers/isValidUTCTimeFormat.js +14 -0
- package/src/components/incidents/helpers/parseMMDDYYYY.js +7 -0
- package/src/components/incidents/helpers/parseQueryString.js +16 -0
- package/src/components/incidents/helpers/sortTrespassDocuments.js +44 -0
- package/src/components/incidents/helpers/stripHTML.js +11 -0
- package/src/components/incidents/helpers/trespassDocUtils.js +197 -0
- package/src/components/incidents/helpers/validateTrespassDetails.js +37 -0
- package/src/components/incidents/usePersistedColModalLink.js +70 -0
- package/src/components/incidents/usePersistedColumns.js +70 -0
- package/src/components/incidents/usePersistedSort.js +23 -0
- package/src/components/incidents/usePersistedSortModalLink.js +23 -0
- package/src/contexts/IncidentContext.js +433 -0
- package/src/index.js +61 -0
- package/src/routes/Application.js +13 -0
- package/src/settings/GetIncidentCategories.js +56 -0
- package/src/settings/GetIncidentTypesDetails.js +88 -0
- package/src/settings/GetIncidentTypesIds.js +74 -0
- package/src/settings/GetLocationsInService.js +54 -0
- package/src/settings/GetSingleCustomLocationDetails.js +60 -0
- package/src/settings/GetSingleIncidentTypeDetails.js +60 -0
- package/src/settings/GetTrespassReasons.js +67 -0
- package/src/settings/GetTrespassTemplates.js +51 -0
- package/src/settings/IncidentCategoriesPane.js +285 -0
- package/src/settings/IncidentCategoriesPane.test.js +229 -0
- package/src/settings/IncidentTypeDetailsPane.js +215 -0
- package/src/settings/IncidentTypeDetailsPane.test.js +220 -0
- package/src/settings/IncidentTypeEditPane.js +211 -0
- package/src/settings/IncidentTypeEditPane.test.js +170 -0
- package/src/settings/IncidentTypesPaneset.js +167 -0
- package/src/settings/IncidentTypesPaneset.test.js +124 -0
- package/src/settings/LocationInServiceEditPane.js +320 -0
- package/src/settings/LocationsPaneset.js +415 -0
- package/src/settings/LocationsPaneset.test.js +106 -0
- package/src/settings/ModalDeleteCategory.js +47 -0
- package/src/settings/ModalDeleteIncidentType.js +49 -0
- package/src/settings/ModalDeleteLocationInService.js +49 -0
- package/src/settings/ModalDeleteTrespassReason.js +49 -0
- package/src/settings/ModalPreviewTrespassDoc.js +65 -0
- package/src/settings/ModalTrespassDocTokens.js +83 -0
- package/src/settings/NewIncidentTypePane.js +182 -0
- package/src/settings/PutIncidentType.js +60 -0
- package/src/settings/PutLocationsInService.js +52 -0
- package/src/settings/PutTrespassReasons.js +61 -0
- package/src/settings/PutTrespassTemplate.js +50 -0
- package/src/settings/TrespassDoc.css +17 -0
- package/src/settings/TrespassDocDetailsPane.js +215 -0
- package/src/settings/TrespassDocEditPane.js +538 -0
- package/src/settings/TrespassDocPaneset.js +581 -0
- package/src/settings/TrespassReasonDetailsPane.js +171 -0
- package/src/settings/TrespassReasonEditPane.js +221 -0
- package/src/settings/TrespassReasonsPaneset.js +282 -0
- package/src/settings/__snapshots__/IncidentCategoriesPane.test.js.snap +3 -0
- package/src/settings/__snapshots__/IncidentTypeDetailsPane.test.js.snap +3 -0
- package/src/settings/__snapshots__/IncidentTypeEditPane.test.js.snap +3 -0
- package/src/settings/__snapshots__/IncidentTypesPaneset.test.js.snap +3 -0
- package/src/settings/__snapshots__/LocationsPaneset.test.js.snap +3 -0
- package/src/settings/data/exampleJSON.json +92 -0
- package/src/settings/data/templateTokens.js +396 -0
- package/src/settings/helpers/alphabetize.js +18 -0
- package/src/settings/helpers/getCategoryTitleById.js +13 -0
- package/src/settings/helpers/makeId.js +15 -0
- package/src/settings/index.js +48 -0
- package/stripes.config.js +10 -0
- package/test/jest/__mock__/index.js +8 -0
- package/test/jest/__mock__/intl.mock.js +27 -0
- package/test/jest/__mock__/stripes.mock.js +26 -0
- package/test/jest/__mock__/stripesComponents.mock.js +151 -0
- package/test/jest/__mock__/stripesConfig.mock.js +1 -0
- package/test/jest/__mock__/stripesCore.mock.js +9 -0
- package/test/jest/__mock__/stripesIcon.mock.js +5 -0
- package/test/jest/__mock__/stripesSmartComponents.mock.js +7 -0
- package/test/jest/__mock__/stripesUtils.mock.js +3 -0
- package/test/jest/eslintrc.js +12 -0
- package/test/jest/setupFiles.js +5 -0
- package/translations/ui-security-incident/en_US.json +542 -0
- package/ui-module-acceptance-criteria.md +34 -0
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { useIntl, FormattedMessage } from 'react-intl';
|
|
3
|
+
import { useStripes } from '@folio/stripes/core';
|
|
4
|
+
import {
|
|
5
|
+
Button,
|
|
6
|
+
Icon,
|
|
7
|
+
KeyValue,
|
|
8
|
+
LoadingPane,
|
|
9
|
+
Modal,
|
|
10
|
+
ModalFooter,
|
|
11
|
+
MultiColumnList,
|
|
12
|
+
Pane,
|
|
13
|
+
Paneset,
|
|
14
|
+
PaneHeader,
|
|
15
|
+
SearchField,
|
|
16
|
+
} from '@folio/stripes/components';
|
|
17
|
+
import css from './ModalStyle.css';
|
|
18
|
+
import { useIncidents } from '../../contexts/IncidentContext';
|
|
19
|
+
import ProfilePicture from './helpers/ProfilePicture/ProfilePicture.js';
|
|
20
|
+
import SearchCustomerOrWitness from './SearchCustomerOrWitness';
|
|
21
|
+
|
|
22
|
+
const ModalSelectKnownCustomer = ({
|
|
23
|
+
setFormData,
|
|
24
|
+
formData,
|
|
25
|
+
setRemovedCustomerIds,
|
|
26
|
+
removedCustomerIds,
|
|
27
|
+
context }) => {
|
|
28
|
+
const stripes = useStripes();
|
|
29
|
+
const intl = useIntl();
|
|
30
|
+
const [searchTerm, setSearchTerm] = useState('');
|
|
31
|
+
const [search, setSearch] = useState('');
|
|
32
|
+
|
|
33
|
+
const {
|
|
34
|
+
isModalSelectKnownCustOpen,
|
|
35
|
+
closeModalSelectKnownCust,
|
|
36
|
+
setCustomers,
|
|
37
|
+
customers, // response array
|
|
38
|
+
isLoadingSearch,
|
|
39
|
+
selectedCustomers,
|
|
40
|
+
setSelectedCustomers,
|
|
41
|
+
} = useIncidents();
|
|
42
|
+
|
|
43
|
+
const hasViewProfilePicturePerm = stripes.hasPerm('ui-users.profile-pictures.view');
|
|
44
|
+
|
|
45
|
+
if (!isModalSelectKnownCustOpen) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
let endOflistTotal = 0;
|
|
50
|
+
|
|
51
|
+
if (customers) {
|
|
52
|
+
endOflistTotal = customers.length;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const handleChange = (event) => {
|
|
56
|
+
const term = event.target.value;
|
|
57
|
+
setSearchTerm(term);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const handleSearchSubmit = () => {
|
|
61
|
+
setSearch(searchTerm.trim());
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// toggle handler in context of edit
|
|
65
|
+
const handleToggleCustomer = (data) => {
|
|
66
|
+
const isInstanceCustomer = formData.customers.some(cust => cust.id === data.id);
|
|
67
|
+
const isRemovedCustomer = removedCustomerIds.includes(data.id);
|
|
68
|
+
// handle remove instance customer
|
|
69
|
+
if (isInstanceCustomer && !isRemovedCustomer) {
|
|
70
|
+
setFormData(prevFormData => ({
|
|
71
|
+
...prevFormData,
|
|
72
|
+
customers: prevFormData.customers.filter(cust => cust.id !== data.id)
|
|
73
|
+
}));
|
|
74
|
+
setRemovedCustomerIds(prev => [...prev, data.id]); //mark as removed
|
|
75
|
+
return;
|
|
76
|
+
};
|
|
77
|
+
// handle adding / removing from selected customers
|
|
78
|
+
setSelectedCustomers((prevState) => {
|
|
79
|
+
console.log("setSelectedCustomers - prevState --> ", JSON.stringify(prevState, null, 2))
|
|
80
|
+
const index = prevState.findIndex((cust) => cust.id === data.id);
|
|
81
|
+
if (index > -1) {
|
|
82
|
+
// remove customer from selectedCustomers
|
|
83
|
+
return prevState.filter((cust) => cust.id !== data.id);
|
|
84
|
+
} else {
|
|
85
|
+
// add customer to selectedCustomers
|
|
86
|
+
return [...prevState, data];
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
// if customer previously removed,
|
|
90
|
+
// this treats selection as new selected customer
|
|
91
|
+
// and remove from removedCustomerIds
|
|
92
|
+
if(isRemovedCustomer) {
|
|
93
|
+
setRemovedCustomerIds(prev => prev.filter(id => id !== data.id));
|
|
94
|
+
};
|
|
95
|
+
// allow keyboard only users immediate access to the close button on select
|
|
96
|
+
document.getElementById('close-continue-button').focus();
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
// toggle handler in context of create
|
|
100
|
+
const handleToggleCustomerCreate = (data) => {
|
|
101
|
+
setSelectedCustomers((prevState) => {
|
|
102
|
+
const index = prevState.findIndex((cust) => cust.id === data.id);
|
|
103
|
+
if (index > -1) {
|
|
104
|
+
// remove customer from selectedCustomers
|
|
105
|
+
return prevState.filter((cust) => cust.id !== data.id);
|
|
106
|
+
} else {
|
|
107
|
+
// add customer to selectedCustomers
|
|
108
|
+
return [...prevState, data];
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
// allow keyboard only users immediate access to the close button on select
|
|
112
|
+
document.getElementById('close-continue-button').focus();
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
const handleSave = () => {
|
|
117
|
+
closeModalSelectKnownCust();
|
|
118
|
+
setCustomers([]);
|
|
119
|
+
setSearch('');
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
const handleDismissClose = () => {
|
|
123
|
+
closeModalSelectKnownCust();
|
|
124
|
+
setCustomers([]);
|
|
125
|
+
setSearch('');
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const handleKeyDown = (event) => {
|
|
129
|
+
if (event.key === 'Enter') {
|
|
130
|
+
handleSearchSubmit();
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
// results formatter in context of edit
|
|
135
|
+
const resultsFormatter = {
|
|
136
|
+
active: (item) => {
|
|
137
|
+
const isActive = item.active === true;
|
|
138
|
+
return <p>{isActive ?
|
|
139
|
+
(<FormattedMessage id="modal-select-customer.resultsFormatter-active"/>)
|
|
140
|
+
:
|
|
141
|
+
(<FormattedMessage id="modal-select-customer.resultsFormatter-inactive"/>)}
|
|
142
|
+
</p>;
|
|
143
|
+
},
|
|
144
|
+
id: (item) => {
|
|
145
|
+
const isCustSelected = selectedCustomers.some(
|
|
146
|
+
(cust) => cust.id === item.id
|
|
147
|
+
);
|
|
148
|
+
const isInstanceCustomer = formData.customers.some(
|
|
149
|
+
(cust) => cust.id === item.id
|
|
150
|
+
);
|
|
151
|
+
const isRemovedCustomer = removedCustomerIds.includes(item.id);
|
|
152
|
+
const showCheckMark = (isCustSelected || isInstanceCustomer) && !isRemovedCustomer;
|
|
153
|
+
const buttonStyle = showCheckMark ? 'success' : 'primary';
|
|
154
|
+
const buttonText = showCheckMark ? <Icon icon="check-circle" /> : 'Add';
|
|
155
|
+
const custData = {
|
|
156
|
+
id: item.id,
|
|
157
|
+
lastName: item.lastName,
|
|
158
|
+
firstName: item.firstName,
|
|
159
|
+
barcode: item.barcode,
|
|
160
|
+
registered: true,
|
|
161
|
+
};
|
|
162
|
+
return (
|
|
163
|
+
<Button
|
|
164
|
+
onClick={() => handleToggleCustomer(custData)}
|
|
165
|
+
buttonStyle={buttonStyle}
|
|
166
|
+
>
|
|
167
|
+
{buttonText}
|
|
168
|
+
</Button>
|
|
169
|
+
);
|
|
170
|
+
},
|
|
171
|
+
name: (item) => {
|
|
172
|
+
if (item.middleName && item.middleName !== '') {
|
|
173
|
+
return `${item.lastName}, ${item.firstName} ${item.middleName}`;
|
|
174
|
+
} else {
|
|
175
|
+
return `${item.lastName}, ${item.firstName}`;
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
profilePicLinkOrUUID: (item) => {
|
|
179
|
+
return (
|
|
180
|
+
<div style={{
|
|
181
|
+
height: '100%',
|
|
182
|
+
width: '100%',
|
|
183
|
+
display: 'flex',
|
|
184
|
+
justifyContent: 'center', // horizontal
|
|
185
|
+
alignItems: 'center' // vertical
|
|
186
|
+
}}>
|
|
187
|
+
{/* fixed-size box to prevent overflow/shift */}
|
|
188
|
+
<div
|
|
189
|
+
style={{
|
|
190
|
+
width: 100,
|
|
191
|
+
height: 100,
|
|
192
|
+
display: 'flex',
|
|
193
|
+
alignItems: 'center',
|
|
194
|
+
justifyContent: 'center'
|
|
195
|
+
}}>
|
|
196
|
+
<ProfilePicture profilePictureLink={item.profilePicLinkOrUUID} />
|
|
197
|
+
</div>
|
|
198
|
+
</div>
|
|
199
|
+
)
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
// results formatter in context of create
|
|
204
|
+
const resultsFormatterCreate = {
|
|
205
|
+
active: (item) => {
|
|
206
|
+
return <p>{item.active ?
|
|
207
|
+
(<FormattedMessage id="modal-select-customer.resultsFormatter-active"/>)
|
|
208
|
+
:
|
|
209
|
+
(<FormattedMessage id="modal-select-customer.resultsFormatter-inactive"/>)}
|
|
210
|
+
</p>;
|
|
211
|
+
},
|
|
212
|
+
id: (item) => {
|
|
213
|
+
const isCustSelected = selectedCustomers.some(
|
|
214
|
+
(cust) => cust.id === item.id
|
|
215
|
+
);
|
|
216
|
+
const buttonStyle = isCustSelected ? 'success' : 'primary';
|
|
217
|
+
const buttonText = isCustSelected ? <Icon icon="check-circle" /> : 'Add';
|
|
218
|
+
const custData = {
|
|
219
|
+
id: item.id,
|
|
220
|
+
lastName: item.lastName,
|
|
221
|
+
firstName: item.firstName,
|
|
222
|
+
barcode: item.barcode,
|
|
223
|
+
registered: true,
|
|
224
|
+
};
|
|
225
|
+
return (
|
|
226
|
+
<Button
|
|
227
|
+
onClick={() => handleToggleCustomerCreate(custData)}
|
|
228
|
+
buttonStyle={buttonStyle}
|
|
229
|
+
>
|
|
230
|
+
{buttonText}
|
|
231
|
+
</Button>
|
|
232
|
+
);
|
|
233
|
+
},
|
|
234
|
+
name: (item) => {
|
|
235
|
+
if (item.middleName && item.middleName !== '') {
|
|
236
|
+
return `${item.lastName}, ${item.firstName} ${item.middleName}`;
|
|
237
|
+
} else {
|
|
238
|
+
return `${item.lastName}, ${item.firstName}`;
|
|
239
|
+
}
|
|
240
|
+
},
|
|
241
|
+
profilePicLinkOrUUID: (item) => {
|
|
242
|
+
return (
|
|
243
|
+
<div style={{
|
|
244
|
+
height: '100%',
|
|
245
|
+
width: '100%',
|
|
246
|
+
display: 'flex',
|
|
247
|
+
justifyContent: 'center', // horizontal
|
|
248
|
+
alignItems: 'center' // vertical
|
|
249
|
+
}}>
|
|
250
|
+
{/* fixed-size box to prevent overflow/shift */}
|
|
251
|
+
<div
|
|
252
|
+
style={{
|
|
253
|
+
width: 100,
|
|
254
|
+
height: 100,
|
|
255
|
+
display: 'flex',
|
|
256
|
+
alignItems: 'center',
|
|
257
|
+
justifyContent: 'center'
|
|
258
|
+
}}>
|
|
259
|
+
<ProfilePicture profilePictureLink={item.profilePicLinkOrUUID} />
|
|
260
|
+
</div>
|
|
261
|
+
</div>
|
|
262
|
+
)
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
const isFormDataPresent = () => {
|
|
267
|
+
const isTermValid = searchTerm && searchTerm.trim() !== '';
|
|
268
|
+
return isTermValid;
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
const resultCount = intl.formatMessage(
|
|
272
|
+
{ id: `modal-select-customer.results-pane.paneSubTitle` },
|
|
273
|
+
{ count: customers.length }
|
|
274
|
+
);
|
|
275
|
+
|
|
276
|
+
const renderHeader = (renderProps) => (
|
|
277
|
+
<PaneHeader
|
|
278
|
+
{...renderProps}
|
|
279
|
+
paneTitle={<FormattedMessage id="modal-select-customer.paneTitle" />}
|
|
280
|
+
paneSub={resultCount}
|
|
281
|
+
/>
|
|
282
|
+
);
|
|
283
|
+
|
|
284
|
+
const footer = (
|
|
285
|
+
<ModalFooter>
|
|
286
|
+
<Button
|
|
287
|
+
id="close-continue-button"
|
|
288
|
+
onClick={handleSave}
|
|
289
|
+
buttonStyle="primary"
|
|
290
|
+
marginBottom0
|
|
291
|
+
>
|
|
292
|
+
<FormattedMessage id="close-continue-button" />
|
|
293
|
+
</Button>
|
|
294
|
+
<Button onClick={handleDismissClose}>
|
|
295
|
+
<FormattedMessage id="cancel-button" />
|
|
296
|
+
</Button>
|
|
297
|
+
</ModalFooter>
|
|
298
|
+
);
|
|
299
|
+
|
|
300
|
+
return (
|
|
301
|
+
<Modal
|
|
302
|
+
style={{
|
|
303
|
+
minHeight: '550px',
|
|
304
|
+
height: '80%', // allows modal to grow/shrink based on content
|
|
305
|
+
maxHeight: '300vh',
|
|
306
|
+
maxWidth: '400vw', // modal width responsive to viewport width
|
|
307
|
+
width: '70%' // modal width adjusts based on content and window size
|
|
308
|
+
}}
|
|
309
|
+
open
|
|
310
|
+
dismissible
|
|
311
|
+
closeOnBackgroundClick
|
|
312
|
+
label={<FormattedMessage id="modal-select-customer.paneTitle" />}
|
|
313
|
+
size="large"
|
|
314
|
+
onClose={handleDismissClose}
|
|
315
|
+
footer={footer}
|
|
316
|
+
contentClass={css.modalContent}
|
|
317
|
+
>
|
|
318
|
+
<div className={css.modalBody}>
|
|
319
|
+
{search && <SearchCustomerOrWitness term={search} />}
|
|
320
|
+
|
|
321
|
+
<Paneset style={{ height: '100%', flexGrow: 1 }}>
|
|
322
|
+
<Pane
|
|
323
|
+
paneTitle={
|
|
324
|
+
<FormattedMessage id="modal-select-customer.search-pane.paneTitle" />
|
|
325
|
+
}
|
|
326
|
+
defaultWidth="25%"
|
|
327
|
+
>
|
|
328
|
+
<SearchField
|
|
329
|
+
placeholder="Name or barcode"
|
|
330
|
+
value=""
|
|
331
|
+
onChange={handleChange}
|
|
332
|
+
onKeyDown={handleKeyDown}
|
|
333
|
+
/>
|
|
334
|
+
<Button
|
|
335
|
+
disabled={!isFormDataPresent()}
|
|
336
|
+
onClick={handleSearchSubmit}
|
|
337
|
+
>
|
|
338
|
+
<FormattedMessage id="search-button" />
|
|
339
|
+
</Button>
|
|
340
|
+
</Pane>
|
|
341
|
+
|
|
342
|
+
{isLoadingSearch ? (
|
|
343
|
+
<LoadingPane
|
|
344
|
+
defaultWidth="fill"
|
|
345
|
+
paneTitle={
|
|
346
|
+
<FormattedMessage id="modal-select-customer.loading-pane-paneTitle" />
|
|
347
|
+
}
|
|
348
|
+
/>
|
|
349
|
+
) : (
|
|
350
|
+
<Pane
|
|
351
|
+
paneTitle={
|
|
352
|
+
<FormattedMessage id="modal-select-customer.results-pane-paneTitle" />
|
|
353
|
+
}
|
|
354
|
+
defaultWidth="75%"
|
|
355
|
+
style={{ overflowY: 'auto', flexGrow: 1 }}
|
|
356
|
+
renderHeader={renderHeader}
|
|
357
|
+
>
|
|
358
|
+
<div className={css.mclContainer}>
|
|
359
|
+
<MultiColumnList
|
|
360
|
+
autosize
|
|
361
|
+
virtualize
|
|
362
|
+
totalCount={endOflistTotal}
|
|
363
|
+
contentData={customers}
|
|
364
|
+
columnWidths={{ profilePicLinkOrUUID: '120px' }}
|
|
365
|
+
visibleColumns={hasViewProfilePicturePerm ? [
|
|
366
|
+
'name',
|
|
367
|
+
'active',
|
|
368
|
+
'barcode',
|
|
369
|
+
'profilePicLinkOrUUID',
|
|
370
|
+
'id'
|
|
371
|
+
] : [
|
|
372
|
+
'name',
|
|
373
|
+
'active',
|
|
374
|
+
'barcode',
|
|
375
|
+
'id'
|
|
376
|
+
]}
|
|
377
|
+
columnMapping={{
|
|
378
|
+
name: <FormattedMessage id="column-mapping.name" />,
|
|
379
|
+
active: <FormattedMessage id="column-mapping.active" />,
|
|
380
|
+
barcode: <FormattedMessage id="column-mapping.barcode" />,
|
|
381
|
+
profilePicLinkOrUUID: <FormattedMessage id="column-mapping.profilePicture" />,
|
|
382
|
+
id: 'Add',
|
|
383
|
+
}}
|
|
384
|
+
formatter={context === 'edit' ? resultsFormatter : resultsFormatterCreate}
|
|
385
|
+
/>
|
|
386
|
+
</div>
|
|
387
|
+
</Pane>
|
|
388
|
+
)}
|
|
389
|
+
</Paneset>
|
|
390
|
+
</div>
|
|
391
|
+
</Modal>
|
|
392
|
+
);
|
|
393
|
+
};
|
|
394
|
+
|
|
395
|
+
export default ModalSelectKnownCustomer;
|