@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.
Files changed (188) hide show
  1. package/.eslintrc +32 -0
  2. package/.github/workflows/CODEOWNERS +8 -0
  3. package/.github/workflows/pr-validation.yml +44 -0
  4. package/.github/workflows/release.yml +64 -0
  5. package/.prettierrc +6 -0
  6. package/.stripesclirc +4 -0
  7. package/CHANGELOG.md +8 -0
  8. package/CONTRIBUTING.md +4 -0
  9. package/LICENSE +201 -0
  10. package/README.md +16 -0
  11. package/administrator-documentation/roles-and-permissions.md +65 -0
  12. package/administrator-documentation/track-settings-admin-guide-sketch.md +192 -0
  13. package/administrator-documentation/using-the-application.md +192 -0
  14. package/icons/app.png +0 -0
  15. package/icons/app.svg +1 -0
  16. package/icons/playButton.png +0 -0
  17. package/icons/profilePicThumbnail.png +0 -0
  18. package/jest.config.js +10 -0
  19. package/module-descriptor.json +75 -0
  20. package/output/service-worker.js +0 -0
  21. package/package.json +146 -0
  22. package/src/components/incidents/ColumnChooser.js +37 -0
  23. package/src/components/incidents/CreateMedia.js +132 -0
  24. package/src/components/incidents/CreatePane.js +1215 -0
  25. package/src/components/incidents/CreatePane.test.js +138 -0
  26. package/src/components/incidents/CreateReport.js +102 -0
  27. package/src/components/incidents/DetailsPane.js +1267 -0
  28. package/src/components/incidents/DetailsPane.test.js +150 -0
  29. package/src/components/incidents/EditPane.js +2334 -0
  30. package/src/components/incidents/EditPane.test.js +187 -0
  31. package/src/components/incidents/GetDetails.js +55 -0
  32. package/src/components/incidents/GetListDQLinkIncident.js +81 -0
  33. package/src/components/incidents/GetListDynamicQuery.js +66 -0
  34. package/src/components/incidents/GetLocations.js +57 -0
  35. package/src/components/incidents/GetMedia.js +98 -0
  36. package/src/components/incidents/GetName.js +111 -0
  37. package/src/components/incidents/GetNameCreatedBy.js +94 -0
  38. package/src/components/incidents/GetOrgLocaleSettings.js +61 -0
  39. package/src/components/incidents/GetPatronGroups.js +52 -0
  40. package/src/components/incidents/GetSelf.js +65 -0
  41. package/src/components/incidents/GetSummary.js +110 -0
  42. package/src/components/incidents/IncidentTypeCard.js +53 -0
  43. package/src/components/incidents/IncidentTypeCard.test.js +133 -0
  44. package/src/components/incidents/IncidentsPaneset.js +810 -0
  45. package/src/components/incidents/IncidentsPaneset.test.js +128 -0
  46. package/src/components/incidents/LinkedIncident.js +86 -0
  47. package/src/components/incidents/ModalAddMedia.js +262 -0
  48. package/src/components/incidents/ModalAddMedia.test.js +97 -0
  49. package/src/components/incidents/ModalAttentionDecOfService.js +111 -0
  50. package/src/components/incidents/ModalCustomWitness.js +469 -0
  51. package/src/components/incidents/ModalCustomWitness.test.js +147 -0
  52. package/src/components/incidents/ModalCustomerDetails.js +480 -0
  53. package/src/components/incidents/ModalCustomerDetails.test.js +116 -0
  54. package/src/components/incidents/ModalDescribeCustomer.js +361 -0
  55. package/src/components/incidents/ModalDescribeCustomer.test.js +156 -0
  56. package/src/components/incidents/ModalDirtyFormWarn.js +62 -0
  57. package/src/components/incidents/ModalLinkIncident.js +1213 -0
  58. package/src/components/incidents/ModalLinkIncidentStyle.css +32 -0
  59. package/src/components/incidents/ModalSelectIncidentTypes.js +178 -0
  60. package/src/components/incidents/ModalSelectIncidentTypes.test.js +273 -0
  61. package/src/components/incidents/ModalSelectKnownCustomer.js +395 -0
  62. package/src/components/incidents/ModalSelectWitness.js +406 -0
  63. package/src/components/incidents/ModalSelectWitness.test.js +308 -0
  64. package/src/components/incidents/ModalStyle.css +44 -0
  65. package/src/components/incidents/ModalTrespass.js +741 -0
  66. package/src/components/incidents/ModalViewCustomerDetails.js +241 -0
  67. package/src/components/incidents/ModalViewMedia.js +86 -0
  68. package/src/components/incidents/ModalViewTrespass.js +210 -0
  69. package/src/components/incidents/ResultsPane.js +437 -0
  70. package/src/components/incidents/ResultsPane.test.js +120 -0
  71. package/src/components/incidents/SearchCustomerOrWitness.js +108 -0
  72. package/src/components/incidents/Thumbnail.js +72 -0
  73. package/src/components/incidents/ThumbnailMarkRemoval.js +38 -0
  74. package/src/components/incidents/ThumbnailSkeleton.js +30 -0
  75. package/src/components/incidents/ThumbnailStyles.js +49 -0
  76. package/src/components/incidents/ThumbnailTempPreSave.js +71 -0
  77. package/src/components/incidents/UpdateReport.js +84 -0
  78. package/src/components/incidents/__snapshots__/CreatePane.test.js.snap +3 -0
  79. package/src/components/incidents/__snapshots__/DetailsPane.test.js.snap +3 -0
  80. package/src/components/incidents/__snapshots__/EditPane.test.js.snap +3 -0
  81. package/src/components/incidents/__snapshots__/IncidentTypeCard.test.js.snap +3 -0
  82. package/src/components/incidents/__snapshots__/IncidentsPaneset.test.js.snap +3 -0
  83. package/src/components/incidents/__snapshots__/ModalAddMedia.test.js.snap +3 -0
  84. package/src/components/incidents/__snapshots__/ModalCustomerDetails.test.js.snap +3 -0
  85. package/src/components/incidents/__snapshots__/ModalSelectWitness.test.js.snap +3 -0
  86. package/src/components/incidents/__snapshots__/ResultsPane.test.js.snap +3 -0
  87. package/src/components/incidents/helpers/ProfilePicture/ProfilePicture.css +5 -0
  88. package/src/components/incidents/helpers/ProfilePicture/ProfilePicture.js +51 -0
  89. package/src/components/incidents/helpers/ProfilePicture/isAValidURL.js +3 -0
  90. package/src/components/incidents/helpers/ProfilePicture/useProfilePicture.js +127 -0
  91. package/src/components/incidents/helpers/buildQueryString.js +28 -0
  92. package/src/components/incidents/helpers/cleanFormValues.js +53 -0
  93. package/src/components/incidents/helpers/computeEditedCustomers.js +124 -0
  94. package/src/components/incidents/helpers/convertDateIgnoringTZ.js +8 -0
  95. package/src/components/incidents/helpers/convertUTCISOToLocalePrettyTime.js +15 -0
  96. package/src/components/incidents/helpers/convertUTCISOToPrettyDate.js +19 -0
  97. package/src/components/incidents/helpers/decodeParamsToForm.js +20 -0
  98. package/src/components/incidents/helpers/deepNormalizeForComparison.js +39 -0
  99. package/src/components/incidents/helpers/extractFilterString.js +12 -0
  100. package/src/components/incidents/helpers/formatDateAndTimeToUTCISO.js +14 -0
  101. package/src/components/incidents/helpers/formatDateToUTCISO.js +14 -0
  102. package/src/components/incidents/helpers/formatTimeToUTCISO.js +28 -0
  103. package/src/components/incidents/helpers/getCurrentTime.js +20 -0
  104. package/src/components/incidents/helpers/getTodayDate.js +12 -0
  105. package/src/components/incidents/helpers/handlebarsHelpers.js +148 -0
  106. package/src/components/incidents/helpers/hasFormChangedAtCreate.js +50 -0
  107. package/src/components/incidents/helpers/hasTopLevelChangeAffectedDeclaration.js +90 -0
  108. package/src/components/incidents/helpers/hasTopLevelFormChanged.js +111 -0
  109. package/src/components/incidents/helpers/identifyCurrentTrespassDocs.js +109 -0
  110. package/src/components/incidents/helpers/isSameHtml.js +13 -0
  111. package/src/components/incidents/helpers/isValidDateFormat.js +14 -0
  112. package/src/components/incidents/helpers/isValidTimeInput.js +11 -0
  113. package/src/components/incidents/helpers/isValidUTCTimeFormat.js +14 -0
  114. package/src/components/incidents/helpers/parseMMDDYYYY.js +7 -0
  115. package/src/components/incidents/helpers/parseQueryString.js +16 -0
  116. package/src/components/incidents/helpers/sortTrespassDocuments.js +44 -0
  117. package/src/components/incidents/helpers/stripHTML.js +11 -0
  118. package/src/components/incidents/helpers/trespassDocUtils.js +197 -0
  119. package/src/components/incidents/helpers/validateTrespassDetails.js +37 -0
  120. package/src/components/incidents/usePersistedColModalLink.js +70 -0
  121. package/src/components/incidents/usePersistedColumns.js +70 -0
  122. package/src/components/incidents/usePersistedSort.js +23 -0
  123. package/src/components/incidents/usePersistedSortModalLink.js +23 -0
  124. package/src/contexts/IncidentContext.js +433 -0
  125. package/src/index.js +61 -0
  126. package/src/routes/Application.js +13 -0
  127. package/src/settings/GetIncidentCategories.js +56 -0
  128. package/src/settings/GetIncidentTypesDetails.js +88 -0
  129. package/src/settings/GetIncidentTypesIds.js +74 -0
  130. package/src/settings/GetLocationsInService.js +54 -0
  131. package/src/settings/GetSingleCustomLocationDetails.js +60 -0
  132. package/src/settings/GetSingleIncidentTypeDetails.js +60 -0
  133. package/src/settings/GetTrespassReasons.js +67 -0
  134. package/src/settings/GetTrespassTemplates.js +51 -0
  135. package/src/settings/IncidentCategoriesPane.js +285 -0
  136. package/src/settings/IncidentCategoriesPane.test.js +229 -0
  137. package/src/settings/IncidentTypeDetailsPane.js +215 -0
  138. package/src/settings/IncidentTypeDetailsPane.test.js +220 -0
  139. package/src/settings/IncidentTypeEditPane.js +211 -0
  140. package/src/settings/IncidentTypeEditPane.test.js +170 -0
  141. package/src/settings/IncidentTypesPaneset.js +167 -0
  142. package/src/settings/IncidentTypesPaneset.test.js +124 -0
  143. package/src/settings/LocationInServiceEditPane.js +320 -0
  144. package/src/settings/LocationsPaneset.js +415 -0
  145. package/src/settings/LocationsPaneset.test.js +106 -0
  146. package/src/settings/ModalDeleteCategory.js +47 -0
  147. package/src/settings/ModalDeleteIncidentType.js +49 -0
  148. package/src/settings/ModalDeleteLocationInService.js +49 -0
  149. package/src/settings/ModalDeleteTrespassReason.js +49 -0
  150. package/src/settings/ModalPreviewTrespassDoc.js +65 -0
  151. package/src/settings/ModalTrespassDocTokens.js +83 -0
  152. package/src/settings/NewIncidentTypePane.js +182 -0
  153. package/src/settings/PutIncidentType.js +60 -0
  154. package/src/settings/PutLocationsInService.js +52 -0
  155. package/src/settings/PutTrespassReasons.js +61 -0
  156. package/src/settings/PutTrespassTemplate.js +50 -0
  157. package/src/settings/TrespassDoc.css +17 -0
  158. package/src/settings/TrespassDocDetailsPane.js +215 -0
  159. package/src/settings/TrespassDocEditPane.js +538 -0
  160. package/src/settings/TrespassDocPaneset.js +581 -0
  161. package/src/settings/TrespassReasonDetailsPane.js +171 -0
  162. package/src/settings/TrespassReasonEditPane.js +221 -0
  163. package/src/settings/TrespassReasonsPaneset.js +282 -0
  164. package/src/settings/__snapshots__/IncidentCategoriesPane.test.js.snap +3 -0
  165. package/src/settings/__snapshots__/IncidentTypeDetailsPane.test.js.snap +3 -0
  166. package/src/settings/__snapshots__/IncidentTypeEditPane.test.js.snap +3 -0
  167. package/src/settings/__snapshots__/IncidentTypesPaneset.test.js.snap +3 -0
  168. package/src/settings/__snapshots__/LocationsPaneset.test.js.snap +3 -0
  169. package/src/settings/data/exampleJSON.json +92 -0
  170. package/src/settings/data/templateTokens.js +396 -0
  171. package/src/settings/helpers/alphabetize.js +18 -0
  172. package/src/settings/helpers/getCategoryTitleById.js +13 -0
  173. package/src/settings/helpers/makeId.js +15 -0
  174. package/src/settings/index.js +48 -0
  175. package/stripes.config.js +10 -0
  176. package/test/jest/__mock__/index.js +8 -0
  177. package/test/jest/__mock__/intl.mock.js +27 -0
  178. package/test/jest/__mock__/stripes.mock.js +26 -0
  179. package/test/jest/__mock__/stripesComponents.mock.js +151 -0
  180. package/test/jest/__mock__/stripesConfig.mock.js +1 -0
  181. package/test/jest/__mock__/stripesCore.mock.js +9 -0
  182. package/test/jest/__mock__/stripesIcon.mock.js +5 -0
  183. package/test/jest/__mock__/stripesSmartComponents.mock.js +7 -0
  184. package/test/jest/__mock__/stripesUtils.mock.js +3 -0
  185. package/test/jest/eslintrc.js +12 -0
  186. package/test/jest/setupFiles.js +5 -0
  187. package/translations/ui-security-incident/en_US.json +542 -0
  188. package/ui-module-acceptance-criteria.md +34 -0
@@ -0,0 +1,241 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { FormattedMessage } from 'react-intl';
4
+ import {
5
+ AccordionSet,
6
+ Accordion,
7
+ Button,
8
+ Col,
9
+ Headline,
10
+ Modal,
11
+ ModalFooter,
12
+ Pane,
13
+ Paneset,
14
+ Row,
15
+ } from '@folio/stripes/components';
16
+ import { useIncidents } from '../../contexts/IncidentContext';
17
+ import css from './ModalStyle.css';
18
+
19
+ const ModalViewCustomerDetails = ({ customerID, customersForView }) => {
20
+ const { isModalViewCustomerDetails, closeModalViewCustomerDetails } =
21
+ useIncidents();
22
+
23
+ // uses 'description' field in customer object
24
+ const [customerDescription, setCustomerDescription] = useState('');
25
+ // uses 'details' object in customer object
26
+ const [customerDetailsData, setCustomerDetailsData] = useState({
27
+ sex: '',
28
+ race: '',
29
+ height: '',
30
+ weight: '',
31
+ hair: '',
32
+ eyes: '',
33
+ dateOfBirth: '',
34
+ streetAddress: '',
35
+ city: '',
36
+ state: '',
37
+ zipcode: '',
38
+ });
39
+
40
+ useEffect(() => {
41
+ const currentCustomer = customersForView.find(
42
+ (cust) => cust.id === customerID
43
+ );
44
+ if (currentCustomer && currentCustomer.details) {
45
+ const currentDetails = {
46
+ sex: currentCustomer.details.sex || '',
47
+ race: currentCustomer.details.race || '',
48
+ height: currentCustomer.details.height || '',
49
+ weight: currentCustomer.details.weight || '',
50
+ hair: currentCustomer.details.hair || '',
51
+ eyes: currentCustomer.details.eyes || '',
52
+ dateOfBirth: currentCustomer.details.dateOfBirth || '',
53
+ streetAddress: currentCustomer.details.streetAddress || '',
54
+ city: currentCustomer.details.city || '',
55
+ state: currentCustomer.details.state || '',
56
+ zipcode: currentCustomer.details.zipcode || ''
57
+ };
58
+ setCustomerDetailsData(currentDetails);
59
+ }
60
+ if (currentCustomer && currentCustomer.description) {
61
+ const currentDescription = currentCustomer.description || '';
62
+ setCustomerDescription(currentDescription);
63
+ }
64
+ }, [customerID, customersForView]);
65
+
66
+ const createMarkup = (content) => {
67
+ return {__html: content}
68
+ };
69
+
70
+ if (!isModalViewCustomerDetails) {
71
+ return null;
72
+ }
73
+
74
+ const footer = (
75
+ <ModalFooter>
76
+ <Button
77
+ onClick={closeModalViewCustomerDetails}
78
+ buttonStyle="primary"
79
+ marginBottom0
80
+ >
81
+ <FormattedMessage id="close-button" />
82
+ </Button>
83
+ </ModalFooter>
84
+ );
85
+
86
+ return (
87
+ <Modal
88
+ style={{ minHeight: '600px' }}
89
+ open
90
+ dismissible
91
+ onClose={closeModalViewCustomerDetails}
92
+ closeOnBackgroundClick
93
+ label={<FormattedMessage id="modal-view-customer-details-label" />}
94
+ size="large"
95
+ footer={footer}
96
+ contentClass={css.modalContent}
97
+ >
98
+ <Paneset>
99
+ <Pane defaultWidth="100%">
100
+ <AccordionSet>
101
+ <Accordion
102
+ label={
103
+ <FormattedMessage id="modal-view-customer-details.accordion-label-customer-description" />
104
+ }
105
+ >
106
+ <Row>
107
+ <Col xs={4}>
108
+ <div
109
+ dangerouslySetInnerHTML={createMarkup(customerDescription)}>
110
+ </div>
111
+ </Col>
112
+ </Row>
113
+ </Accordion>
114
+ <Accordion
115
+ label={
116
+ <FormattedMessage id="modal-view-customer-details.accordion-label-identity-details" />
117
+ }
118
+ >
119
+ <Row style={{ marginTop: '30px' }}>
120
+ <Col xs={2}>
121
+ <Headline size="medium" tag="h2">
122
+ <FormattedMessage id="modal-view-customer-details.headline-sex" />
123
+ </Headline>
124
+ <p>
125
+ {customerDetailsData.sex ? customerDetailsData.sex : '-'}
126
+ </p>
127
+ </Col>
128
+
129
+ <Col xs={2}>
130
+ <Headline size="medium" tag="h2">
131
+ <FormattedMessage id="modal-view-customer-details.headline-race" />
132
+ </Headline>
133
+ <p>
134
+ {customerDetailsData.race ? customerDetailsData.race : '-'}
135
+ </p>
136
+ </Col>
137
+ <Col xs={2}>
138
+ <Headline size="medium" tag="h2">
139
+ <FormattedMessage id="modal-view-customer-details.headline-weight" />
140
+ </Headline>
141
+ <p>
142
+ {customerDetailsData.height
143
+ ? customerDetailsData.height
144
+ : '-'}
145
+ </p>
146
+ </Col>
147
+ </Row>
148
+
149
+ <Row style={{ marginTop: '30px' }}>
150
+ <Col xs={2}>
151
+ <Headline size="medium" tag="h2">
152
+ <FormattedMessage id="modal-view-customer-details.headline-weight" />
153
+ </Headline>
154
+ <p>
155
+ {customerDetailsData.weight
156
+ ? customerDetailsData.weight
157
+ : '-'}
158
+ </p>
159
+ </Col>
160
+ <Col xs={2}>
161
+ <Headline size="medium" tag="h2">
162
+ <FormattedMessage id="modal-view-customer-details.headline-hair" />
163
+ </Headline>
164
+ <p>
165
+ {customerDetailsData.hair ? customerDetailsData.hair : '-'}
166
+ </p>
167
+ </Col>
168
+ <Col xs={2}>
169
+ <Headline size="medium" tag="h2">
170
+ <FormattedMessage id="modal-view-customer-details.headline-eyes" />
171
+ </Headline>
172
+ <p>
173
+ {customerDetailsData.eyes ? customerDetailsData.eyes : '-'}
174
+ </p>
175
+ </Col>
176
+ </Row>
177
+
178
+ <Row style={{ marginTop: '30px' }}>
179
+ <Col xs={2}>
180
+ <Headline size="medium" tag="h2">
181
+ <FormattedMessage id="modal-view-customer-details.headline-date-of-birth" />
182
+ </Headline>
183
+ <p>
184
+ {customerDetailsData.dateOfBirth
185
+ ? customerDetailsData.dateOfBirth.slice(0, 10)
186
+ : '-'}
187
+ </p>
188
+ </Col>
189
+ <Col xs={2}>
190
+ <Headline size="medium" tag="h2">
191
+ <FormattedMessage id="modal-view-customer-details.headline-street-address" />
192
+ </Headline>
193
+ <p>
194
+ {customerDetailsData.streetAddress
195
+ ? customerDetailsData.streetAddress
196
+ : '-'}
197
+ </p>
198
+ </Col>
199
+ <Col xs={2}>
200
+ <Headline size="medium" tag="h2">
201
+ <FormattedMessage id="modal-view-customer-details.headline-city" />
202
+ </Headline>
203
+ <p>
204
+ {customerDetailsData.city ? customerDetailsData.city : '-'}
205
+ </p>
206
+ </Col>
207
+ <Col xs={2}>
208
+ <Headline size="medium" tag="h2">
209
+ <FormattedMessage id="modal-view-customer-details.headline-state" />
210
+ </Headline>
211
+ <p>
212
+ {customerDetailsData.state
213
+ ? customerDetailsData.state
214
+ : '-'}
215
+ </p>
216
+ </Col>
217
+ <Col xs={2}>
218
+ <Headline size="medium" tag="h2">
219
+ <FormattedMessage id="modal-view-customer-details.headline-zipcode" />
220
+ </Headline>
221
+ <p>
222
+ {customerDetailsData.zipcode
223
+ ? customerDetailsData.zipcode
224
+ : '-'}
225
+ </p>
226
+ </Col>
227
+ </Row>
228
+ </Accordion>
229
+ </AccordionSet>
230
+ </Pane>
231
+ </Paneset>
232
+ </Modal>
233
+ );
234
+ };
235
+
236
+ ModalViewCustomerDetails.propTypes = {
237
+ customerID: PropTypes.string.isRequired,
238
+ customersForView: PropTypes.arrayOf(PropTypes.object).isRequired,
239
+ };
240
+
241
+ export default ModalViewCustomerDetails;
@@ -0,0 +1,86 @@
1
+ import React, { useState } from 'react';
2
+ import { FormattedMessage } from 'react-intl';
3
+ import { Col, Loading, Modal, Row } from '@folio/stripes/components';
4
+ import { useIncidents } from '../../contexts/IncidentContext';
5
+ import GetMedia from './GetMedia';
6
+
7
+ const ModalViewMedia = ({ modalViewImageData }) => {
8
+ const { isModalViewImage, closeModalViewImage } = useIncidents();
9
+ const { id, imageId, alt, contentType, imageDescription} = modalViewImageData;
10
+ const [mediaUrl, setMediaUrl] = useState('');
11
+ const [isLoading, setIsLoading] = useState(true);
12
+
13
+ if (!isModalViewImage) {
14
+ return null;
15
+ };
16
+
17
+ const handleDataResponse = (url) => {
18
+ setMediaUrl(url)
19
+ setIsLoading(false)
20
+ };
21
+
22
+ const isVideo = contentType.startsWith('video');
23
+
24
+ const handleDismissClose = () => {
25
+ closeModalViewImage();
26
+ };
27
+
28
+ return (
29
+ <Modal
30
+ style={{
31
+ minHeight: '550px',
32
+ height: '60%', // allows modal to grow/shrink based on content
33
+ maxHeight: '300vh', // modal will never exceed 90% of viewport height
34
+ maxWidth: '400vw', // modal width responsive to viewport width
35
+ width: '80%' // modal width adjusts based on content and window size
36
+ }}
37
+ open
38
+ dismissible
39
+ closeOnBackgroundClick
40
+ label={imageDescription}
41
+ size="large"
42
+ onClose={handleDismissClose}
43
+ >
44
+ {id && imageId &&
45
+ <GetMedia
46
+ context='original-or-video'
47
+ id={id}
48
+ imageId={imageId}
49
+ handleDataResponse={handleDataResponse}
50
+ />}
51
+
52
+ {isLoading ? (
53
+ <Row style={{ display: 'flex', justifyContent: 'center', marginTop: "150px"}}>
54
+ <Col>
55
+ <div style={{ "display": "flex", "justiftContent": "center", "aligItems": "center", "height": "100%" }}>
56
+ <Loading size='large'/>
57
+ </div>
58
+ </Col>
59
+ </Row>
60
+ ) : (
61
+ <Row style={{ display: 'flex', justifyContent: 'center' }}>
62
+ <Col xs={8} style={{ textAlign: 'center' }}>
63
+ {isVideo ? (
64
+ mediaUrl && <video
65
+ width="650"
66
+ height="auto"
67
+ controls controlsList="nodownload" // do not render download option
68
+ oncontextmenu="return false;" // prevent right click download option
69
+ >
70
+ <source src={mediaUrl} type={contentType}></source>
71
+ <FormattedMessage id="video-player-default-text" />
72
+ </video>
73
+ ) : (mediaUrl && <img
74
+ src={mediaUrl}
75
+ alt={alt}
76
+ style={{ width: '550px', margin: 'auto' }}
77
+ className="img-fluid"
78
+ />)}
79
+ </Col>
80
+ </Row>
81
+ )}
82
+ </Modal>
83
+ );
84
+ };
85
+
86
+ export default ModalViewMedia;
@@ -0,0 +1,210 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { FormattedMessage } from 'react-intl';
4
+ import {
5
+ AccordionSet,
6
+ Accordion,
7
+ Button,
8
+ Col,
9
+ Headline,
10
+ List,
11
+ Modal,
12
+ ModalFooter,
13
+ Pane,
14
+ Paneset,
15
+ Row,
16
+ } from '@folio/stripes/components';
17
+ import { useIncidents } from '../../contexts/IncidentContext';
18
+ import css from './ModalStyle.css';
19
+ import GetLocationsInService from '../../settings/GetLocationsInService';
20
+
21
+ const ModalViewTrespass = ({ customerID, customersForView }) => {
22
+ const {
23
+ isModalViewTrespass,
24
+ closeModalViewTrespass,
25
+ locationsInService
26
+ } = useIncidents();
27
+
28
+ const [trespassData, setTrespassData] = useState({
29
+ dateOfOccurrence: '',
30
+ exclusionOrTrespassBasedOn: [],
31
+ witnessedBy: { witnesses: [] },
32
+ endDateOfTrespass: '',
33
+ declarationOfService: {
34
+ date: '',
35
+ placeSigned: '',
36
+ title: '',
37
+ signature: false,
38
+ },
39
+ });
40
+
41
+ const associatedKeyPlaceSigned = (value) => {
42
+ // value is expected to tbe the id associated w/ locationInService obj
43
+ const locObject = locationsInService.find(loc => loc.id === value)
44
+ // return the obj's location (which is the 'Pretty Name')
45
+ return locObject ? locObject.location : '';
46
+ };
47
+
48
+ useEffect(() => {
49
+ const currentCustomer = customersForView.find(
50
+ (cust) => cust.id === customerID
51
+ );
52
+ if (currentCustomer && currentCustomer.trespass) {
53
+ const trespass = currentCustomer.trespass;
54
+ const declarationOfService = trespass.declarationOfService || {
55
+ date: '',
56
+ placeSigned: '',
57
+ title: '',
58
+ signature: false,
59
+ };
60
+
61
+ const currentDetails = {
62
+ dateOfOccurrence: trespass.dateOfOccurrence || '',
63
+ exclusionOrTrespassBasedOn: trespass.exclusionOrTrespassBasedOn || [],
64
+ endDateOfTrespass: trespass.endDateOfTrespass || '',
65
+ declarationOfService: declarationOfService ? {
66
+ date: declarationOfService.date || '',
67
+ placeSigned: associatedKeyPlaceSigned(declarationOfService.placeSigned) || '',
68
+ title: declarationOfService.title || '',
69
+ signature: declarationOfService.signature || false,
70
+ } : {
71
+ date: '',
72
+ placeSigned: '',
73
+ title: '',
74
+ signature: false,
75
+ },
76
+ };
77
+ setTrespassData(currentDetails);
78
+ }
79
+ }, [customerID, customersForView]);
80
+
81
+ const itemsFormatterExclusionList = (item) => {
82
+ return <li style={{ marginLeft: '10px' }}>{item}</li>;
83
+ };
84
+
85
+ if (!isModalViewTrespass) {
86
+ return null;
87
+ };
88
+
89
+ const footer = (
90
+ <ModalFooter>
91
+ <Button
92
+ onClick={closeModalViewTrespass}
93
+ buttonStyle="primary"
94
+ marginBottom0
95
+ >
96
+ <FormattedMessage id="close-button" />
97
+ </Button>
98
+ </ModalFooter>
99
+ );
100
+
101
+ return (
102
+ <Modal
103
+ style={{ minHeight: '1050px' }}
104
+ open
105
+ dismissible
106
+ onClose={closeModalViewTrespass}
107
+ closeOnBackgroundClick
108
+ label={<FormattedMessage id="modal-view-trespass-label" />}
109
+ size="large"
110
+ footer={footer}
111
+ contentClass={css.modalContent}
112
+ >
113
+ <Paneset>
114
+ <Pane defaultWidth="100%">
115
+ <GetLocationsInService />
116
+ <AccordionSet>
117
+ <Accordion
118
+ label={
119
+ <FormattedMessage id="modal-view-trespass.accordion-trespass-details-label" />
120
+ }
121
+ >
122
+ <Row style={{ marginTop: '15px' }}>
123
+ <Col xs={4}>
124
+ <Headline size="medium" tag="h3">
125
+ <FormattedMessage id="modal-view-trespass.headline-exclusion-based-on" />
126
+ </Headline>
127
+ <List
128
+ label={
129
+ <FormattedMessage id="modal-view-trespass.headline-exclusion-based-on" />
130
+ }
131
+ listStyle="bullets"
132
+ items={trespassData.exclusionOrTrespassBasedOn}
133
+ itemFormatter={itemsFormatterExclusionList}
134
+ isEmptyMessage="-"
135
+ />
136
+ </Col>
137
+ </Row>
138
+ <Row style={{ marginTop: '15px' }}>
139
+ <Col xs={4}>
140
+ <Headline size="medium" tag="h3">
141
+ <FormattedMessage id="modal-view-trespass.headline-end-date-trespass" />
142
+ </Headline>
143
+ <p>
144
+ {trespassData.endDateOfTrespass
145
+ ? trespassData.endDateOfTrespass.slice(0, 10)
146
+ : '-'}
147
+ </p>
148
+ </Col>
149
+ </Row>
150
+ </Accordion>
151
+
152
+ <Accordion
153
+ label={
154
+ <FormattedMessage id="modal-view-trespass.accordion-declaration-of-service-label" />
155
+ }
156
+ >
157
+ <Row style={{ marginTop: '15px' }}>
158
+ <Col xs={2}>
159
+ <Headline size="medium" tag="h3">
160
+ <FormattedMessage id="modal-view-trespass.headline-date-served" />
161
+ </Headline>
162
+ <p>
163
+ {trespassData.declarationOfService.date
164
+ ? trespassData.declarationOfService.date.slice(0, 10)
165
+ : '-'}
166
+ </p>
167
+ </Col>
168
+ <Col xs={2}>
169
+ <Headline size="medium" tag="h3">
170
+ <FormattedMessage id="modal-view-trespass.headline-place-signed" />
171
+ </Headline>
172
+ <p>
173
+ {trespassData.declarationOfService.placeSigned
174
+ ? trespassData.declarationOfService.placeSigned
175
+ : '-'}
176
+ </p>
177
+ </Col>
178
+ <Col xs={2}>
179
+ <Headline size="medium" tag="h3">
180
+ <FormattedMessage id="modal-view-trespass.headline-title" />
181
+ </Headline>
182
+ <p>
183
+ {trespassData.declarationOfService.title
184
+ ? trespassData.declarationOfService.title
185
+ : '-'}
186
+ </p>
187
+ </Col>
188
+ <Col xs={2}>
189
+ <Headline size="medium" tag="h3">
190
+ <FormattedMessage id="modal-view-trespass.headline-signed" />
191
+ </Headline>
192
+ <p>
193
+ {trespassData.declarationOfService.signature ? 'Yes' : '-'}
194
+ </p>
195
+ </Col>
196
+ </Row>
197
+ </Accordion>
198
+ </AccordionSet>
199
+ </Pane>
200
+ </Paneset>
201
+ </Modal>
202
+ );
203
+ };
204
+
205
+ ModalViewTrespass.propTypes = {
206
+ customerID: PropTypes.string.isRequired,
207
+ customersForView: PropTypes.arrayOf(PropTypes.object).isRequired,
208
+ };
209
+
210
+ export default ModalViewTrespass;