@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,3 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`renders without crashing (snapshot) 1`] = `"<div><div defaultwidth="fill" panetitle="[object Object]"><div>Mock GetLocations</div><div>Mock GetLocationsInService</div><div><div label="[object Object]"><div style="margin-top: 25px;"><div xs="6"><select dataoptions="[object Object],[object Object],[object Object],[object Object]"></select></div><div xs="3"><button disabled="" buttonstyle="primary"><span>settings.button.save-loc-to-service</span></button></div></div><div><div xs="10"><div style="height: 300px; width: auto;"><div contentdata="[object Object]" formatter="[object Object]" visiblecolumns="location,subLocations" columnmapping="[object Object]" isemptymessage="[object Object]"></div></div></div></div><div style="margin-top: 25px; margin-bottom: 25px;"><div xs="8"><div style="min-height: 50px;"><div type="success"><span>settings.locations.message-banner.success</span></div></div></div></div></div><div label="[object Object]"><div style="margin-top: 20px;"><div xs="6"><label id="label-name" style="margin-bottom: 12px;"><span>settings.label.name</span></label><input aria-labelledby="label-name" value=""></div><div xs="6" style="margin-top: 20px;"><div><div type="error"><span>settings.locations-zones-messageBanner-error-msg</span></div></div></div></div><div style="margin-top: 20px;"><div xs="4"><label id="label-zones"><span>settings.label.zones</span></label><ul></ul><div><input placeholder="Zone name" value=""><textarea placeholder="Zone description" style="margin-top: 20px;"></textarea><button style="margin-top: 20px;"><span>settings.button.add-zone</span></button></div></div></div><div style="margin-top: 10px;"><div xs="6"><button buttonstyle="primary" disabled=""><span>settings.button.save-new-custom-loc</span></button></div></div></div></div></div><div></div></div>"`;
@@ -0,0 +1,92 @@
1
+ {
2
+ "attachments": [
3
+ {
4
+ "contentType": "image/jpeg",
5
+ "description": "test image of customer",
6
+ "id": "test-image-of-customer"
7
+ },
8
+ {
9
+ "contentType": "application/pdf",
10
+ "description": "SMITH, DANIELLE LOUISE Trespass 02/03/2025",
11
+ "id": "smith-danielle-louise-trespass-02-03-2025"
12
+ }
13
+ ],
14
+ "createdBy": {
15
+ "barcode": "",
16
+ "firstName": "Spokane",
17
+ "id": "8dac9a5a-212b-5f62-a4c4-9c90a56c3a93",
18
+ "lastName": "Administrator"
19
+ },
20
+ "customerNa": false,
21
+ "customers": [
22
+ {
23
+ "barcode": "27413205897683",
24
+ "description": "<p>description of customer Danielle Louise Smith</p>",
25
+ "details": {
26
+ "city": "Spokane",
27
+ "dateOfBirth": "1987-12-18T00:00:00+00:00",
28
+ "eyes": "eyes",
29
+ "hair": "hair",
30
+ "height": "height",
31
+ "race": "race",
32
+ "sex": "sex",
33
+ "state": "WA",
34
+ "streetAddress": "402 W Main Ave",
35
+ "weight": "weight",
36
+ "zipcode": "99201"
37
+ },
38
+ "firstName": "DANIELLE LOUISE",
39
+ "id": "2bb8758a-ba99-3aba-acc8-8c9b43c0f7bb",
40
+ "lastName": "SMITH",
41
+ "registered": true,
42
+ "trespass": {
43
+ "dateOfOccurrence": "2025-02-03T00:00:00+00:00",
44
+ "declarationOfService": {
45
+ "date": "2025-02-03T00:00:00+00:00",
46
+ "placeSigned": "central",
47
+ "signature": true,
48
+ "title": "CXM"
49
+ },
50
+ "descriptionOfOccurrence": "<p>Description of incident involving customer Smith. -updated</p>",
51
+ "endDateOfTrespass": "2025-02-17T08:00:00.000Z",
52
+ "exclusionOrTrespassBasedOn": [
53
+ "Violation of City/State/Federal"
54
+ ],
55
+ "witnessedBy": [
56
+ {
57
+ "firstName": "Spokane",
58
+ "id": "8dac9a5a-212b-5f62-a4c4-9c90a56c3a93",
59
+ "lastName": "Administrator"
60
+ }
61
+ ]
62
+ }
63
+ }
64
+ ],
65
+ "dateTimeOfIncident": "2025-02-03T18:29:00+00:00",
66
+ "detailedDescriptionOfIncident": "<p>Description of incident involving customer Smith. -updated</p>",
67
+ "id": "701f5ee8-a3f7-30bf-a663-d6be7aac00bb",
68
+ "incidentLocation": "central",
69
+ "incidentTypes": [
70
+ {
71
+ "category_id": "level-1-annoying-but-not-dangerous",
72
+ "description": "Failure to comply with a staff request.",
73
+ "id": "1-1",
74
+ "title": "1.1"
75
+ }
76
+ ],
77
+ "incidentWitnesses": [
78
+ {
79
+ "firstName": "Spokane",
80
+ "id": "8dac9a5a-212b-5f62-a4c4-9c90a56c3a93",
81
+ "lastName": "Administrator"
82
+ }
83
+ ],
84
+ "isApproximateTime": true,
85
+ "metadata": {
86
+ "createdByUserId": "8dac9a5a-212b-5f62-a4c4-9c90a56c3a93",
87
+ "createdDate": "2025-02-03T18:31:56.525+00:00",
88
+ "updatedByUserId": "8dac9a5a-212b-5f62-a4c4-9c90a56c3a93",
89
+ "updatedDate": "2025-02-03T18:35:17.527+00:00"
90
+ },
91
+ "subLocation": "North Exterior"
92
+ }
@@ -0,0 +1,396 @@
1
+
2
+ import getTodayDate from "../../components/incidents/helpers/getTodayDate";
3
+ const todayDate = getTodayDate();
4
+ const twoWeeksFromTodayDate = new Date(new Date(todayDate).getTime() + 14 * 24 * 60 * 60 * 1000).toLocaleDateString();
5
+
6
+ // value/label objects for checkbox
7
+ export const tokensArray = [
8
+ {
9
+ label: 'customer.trespass.declarationOfService.user',
10
+ value: '{{declarationOfServiceIssuedBy}}'
11
+ },
12
+
13
+ // WITH resolve helper func syntax:
14
+ {
15
+ label: 'customer.barcode',
16
+ value: '{{resolve "customer.barcode"}}'
17
+ },
18
+ {
19
+ label: 'customer.description',
20
+ value: '{{resolve "customer.description"}}'
21
+ },
22
+ {
23
+ label: 'customer.details.city',
24
+ value: '{{resolve "customer.details.city"}}'
25
+ },
26
+ // {
27
+ // label: 'customer.details.descriptionOfCustomerAtOccurrence',
28
+ // value: '{{resolve "customer.details.descriptionOfCustomerAtOccurrence"}}'
29
+ // },
30
+ {
31
+ label: 'customer.details.eyes',
32
+ value: '{{resolve "customer.details.eyes"}}'
33
+ },
34
+ {
35
+ label: 'customer.details.hair',
36
+ value: '{{resolve "customer.details.hair"}}'
37
+ },
38
+ {
39
+ label: 'customer.details.height',
40
+ value: '{{resolve "customer.details.height"}}'
41
+ },
42
+ {
43
+ label: 'customer.details.race',
44
+ value: '{{resolve "customer.details.race"}}'
45
+ },
46
+ {
47
+ label: 'customer.details.sex',
48
+ value: '{{resolve "customer.details.sex"}}'
49
+ },
50
+ {
51
+ label: 'customer.details.state',
52
+ value: '{{resolve "customer.details.state"}}'
53
+ },
54
+ {
55
+ label: 'customer.details.streetAddress',
56
+ value: '{{resolve "customer.details.streetAddress"}}'
57
+ },
58
+ {
59
+ label: 'customer.details.weight',
60
+ value: '{{resolve "customer.details.weight"}}'
61
+ },
62
+ {
63
+ label: 'customer.details.zipcode',
64
+ value: '{{resolve "customer.details.zipcode"}}'
65
+ },
66
+
67
+ {
68
+ label: 'customer.firstName',
69
+ value: '{{resolve "customer.firstName"}}'
70
+ },
71
+ {
72
+ label: 'customer.lastName',
73
+ value: '{{resolve "customer.lastName"}}'
74
+ },
75
+ {
76
+ label: 'customer.fullName',
77
+ value: '{{resolve "customer.fullName"}}'
78
+ },
79
+
80
+ {
81
+ label: 'customer.trespass.dateOfOccurrence',
82
+ value: '{{formatDate (resolve "customer.trespass.dateOfOccurrence")}}'
83
+ },
84
+ {
85
+ label: 'customer.trespass.declarationOfService.date',
86
+ value: '{{formatDate (resolve "customer.trespass.declarationOfService.date")}}'
87
+ },
88
+
89
+
90
+ {
91
+ label: 'customer.trespass.declarationOfService.placeSigned',
92
+ value: '{{formatLocation customer.trespass.declarationOfService.placeSigned}}'
93
+ },
94
+ {
95
+ label: 'customer.trespass.declarationOfService.signature',
96
+ value: '{{resolve "customer.trespass.declarationOfService.signature"}}'
97
+ },
98
+ {
99
+ label: 'customer.trespass.declarationOfService.title',
100
+ value: '{{resolve "customer.trespass.declarationOfService.title"}}'
101
+ },
102
+ {
103
+ label: 'customer.trespass.descriptionOfOccurrence',
104
+ value: '{{{trespassDescriptionPlain}}}'
105
+ },
106
+ {
107
+ label: 'customer.trespass.endDateOfTrespass',
108
+ value: '{{formatDate (resolve "customer.trespass.endDateOfTrespass")}}'
109
+ },
110
+ // array fields in trespass:
111
+ {
112
+ label: 'customer.trespass.exclusionOrTrespassBasedOn',
113
+ value: '{{resolveTrespassReasons customer.trespass.exclusionOrTrespassBasedOn}}'
114
+ },
115
+ {
116
+ label: 'customer.trespass.witnessedBy.firstName',
117
+ value: '{{resolve "customer.trespass.witnessedBy" property="firstName"}}'
118
+ },
119
+ {
120
+ label: 'customer.trespass.witnessedBy.lastName',
121
+ value: '{{resolve "customer.trespass.witnessedBy" property="lastName"}}'
122
+ },
123
+ {
124
+ label: 'customer.trespass.witnessedBy.fullName',
125
+ value: '{{resolve "customer.trespass.witnessedBy" property="fullName"}}'
126
+ },
127
+ {
128
+ label: 'customer.trespass.witnessedBy.barcode',
129
+ value: '{{resolve "customer.trespass.witnessedBy" property="barcode"}}'
130
+ },
131
+ {
132
+ label: 'customer.trespass.witnessedBy.phone',
133
+ value: '{{resolve "customer.trespass.witnessedBy" property="phone"}}'
134
+ },
135
+ {
136
+ label: 'customer.trespass.witnessedBy.email',
137
+ value: '{{resolve "customer.trespass.witnessedBy" property="email"}}'
138
+ },
139
+ // {
140
+ // label: 'customer.trespass.witnessedBy.role',
141
+ // value: '{{resolve "customer.trespass.witnessedBy" property="role"}}'
142
+ // },
143
+
144
+ // Incident level keys:
145
+ // {
146
+ // label: 'createdBy.firstName',
147
+ // value: '{{createdBy.firstName}}'
148
+ // },
149
+ // {
150
+ // label: 'createdBy.lastName',
151
+ // value: '{{createdBy.lastName}}'
152
+ // },
153
+ // {
154
+ // label: 'dateTimeOfIncident',
155
+ // value: '{{dateTimeOfIncident}}'
156
+ // },
157
+ // {
158
+ // label: 'detailedDescriptionOfIncident',
159
+ // value: '{{detailedDescriptionOfIncident}}'
160
+ // },
161
+ {
162
+ label: 'incidentLocation',
163
+ value: '{{formatLocation incident.incidentLocation}}'
164
+ },
165
+ // {
166
+ // label: 'subLocation',
167
+ // value: '{{subLocation}}'
168
+ // },
169
+
170
+
171
+ {
172
+ label: 'incidentTypes.description',
173
+ value: '{{resolveIncTypes "incident.incidentTypes.description"}}'
174
+ },
175
+ {
176
+ label: 'incidentTypes.title',
177
+ value: '{{resolveIncTypes "incident.incidentTypes.title"}}'
178
+ },
179
+
180
+ // {
181
+ // label: 'incidentWitnesses.firstName',
182
+ // value: '{{incidentWitnesses.firstName}}'
183
+ // },
184
+ // {
185
+ // label: 'incidentWitnesses.lastName',
186
+ // value: '{{incidentWitnesses.lastName}}'
187
+ // },
188
+ // {
189
+ // label: 'incidentWitnesses.barcode',
190
+ // value: '{{incidentWitnesses.barcode}}'
191
+ // },
192
+ // {
193
+ // label: 'incidentWitnesses.phone',
194
+ // value: '{{incidentWitnesses.phone}}'
195
+ // },
196
+ // {
197
+ // label: 'incidentWitnesses.email',
198
+ // value: '{{incidentWitnesses.email}}'
199
+ // },
200
+ // {
201
+ // label: 'incidentWitnesses.role',
202
+ // value: '{{incidentWitnesses.role}}'
203
+ // },
204
+
205
+ // START Customer object level keys
206
+ // {
207
+ // label: 'customer.barcode',
208
+ // value: '{{customer.barcode}}'
209
+ // },
210
+ // {
211
+ // label: 'customer.description',
212
+ // value: '{{customer.description}}'
213
+ // },
214
+
215
+ // {
216
+ // label: 'customer.details.city',
217
+ // value: '{{customer.details.city}}'
218
+ // },
219
+ // {
220
+ // label: 'customer.details.descriptionOfCustomerAtOccurrence',
221
+ // value: '{{customer.details.descriptionOfCustomerAtOccurrence}}'
222
+ // },
223
+ // {
224
+ // label: 'customer.details.eyes',
225
+ // value: '{{customer.details.eyes}}'
226
+ // },
227
+ // {
228
+ // label: 'customer.details.hair',
229
+ // value: '{{customer.details.hair}}'
230
+ // },
231
+ // {
232
+ // label: 'customer.details.height',
233
+ // value: '{{customer.details.height}}'
234
+ // },
235
+ // {
236
+ // label: 'customer.details.race',
237
+ // value: '{{customer.details.race}}'
238
+ // },
239
+ // {
240
+ // label: 'customer.details.sex',
241
+ // value: '{{customer.details.sex}}'
242
+ // },
243
+ // {
244
+ // label: 'customer.details.state',
245
+ // value: '{{customer.details.state}}'
246
+ // },
247
+ // {
248
+ // label: 'customer.details.streetAddress',
249
+ // value: '{{customer.details.streetAddress}}'
250
+ // },
251
+ // {
252
+ // label: 'customer.details.weight',
253
+ // value: '{{customer.details.weight}}'
254
+ // },
255
+ // {
256
+ // label: 'customer.details.zipcode',
257
+ // value: '{{customer.details.zipcode}}'
258
+ // },
259
+
260
+ // {
261
+ // label: 'customer.firstName',
262
+ // value: '{{customer.firstName}}'
263
+ // },
264
+ // {
265
+ // label: 'customer.lastName',
266
+ // value: '{{customer.lastName}}'
267
+ // },
268
+ // {
269
+ // label: 'customer.trespass.dateOfOccurrence',
270
+ // value: '{{customer.trespass.dateOfOccurrence}}'
271
+ // },
272
+ // {
273
+ // label: 'customer.trespass.declarationOfService.date',
274
+ // value: '{{customer.trespass.declarationOfService.date}}'
275
+ // },
276
+ // {
277
+ // label: 'customer.trespass.declarationOfService.placeSigned',
278
+ // value: '{{customer.trespass.declarationOfService.placeSigned}}'
279
+ // },
280
+ // {
281
+ // label: 'customer.trespass.declarationOfService.signature',
282
+ // value: '{{customer.trespass.declarationOfService.signature}}'
283
+ // },
284
+ // {
285
+ // label: 'customer.trespass.declarationOfService.title',
286
+ // value: '{{customer.trespass.declarationOfService.title}}'
287
+ // },
288
+ // {
289
+ // label: 'customer.trespass.descriptionOfOccurrence',
290
+ // value: '{{customer.trespass.descriptionOfOccurrence}}'
291
+ // },
292
+ // {
293
+ // label: 'customer.trespass.endDateOfTrespass',
294
+ // value: '{{customer.trespass.endDateOfTrespass}}'
295
+ // },
296
+ // {
297
+ // label: 'customer.trespass.exclusionOrTrespassBasedOn',
298
+ // value: '{{customer.trespass.exclusionOrTrespassBasedOn}}'
299
+ // },
300
+ // {
301
+ // label: 'customer.trespass.witnessedBy',
302
+ // value: '{{customer.trespass.witnessedBy}}'
303
+ // },
304
+ // {
305
+ // label: 'customer.trespass.witnessedBy.firstName',
306
+ // value: '{{customer.trespass.witnessedBy.firstName}}'
307
+ // },
308
+ // {
309
+ // label: 'customer.trespass.witnessedBy.lastName',
310
+ // value: '{{customer.trespass.witnessedBy.lastName}}'
311
+ // },
312
+ // {
313
+ // label: 'customer.trespass.witnessedBy.barcode',
314
+ // value: '{{customer.trespass.witnessedBy.barcode}}'
315
+ // },
316
+ // {
317
+ // label: 'customer.trespass.witnessedBy.phone',
318
+ // value: '{{customer.trespass.witnessedBy.phone}}'
319
+ // },
320
+ // {
321
+ // label: 'customer.trespass.witnessedBy.email',
322
+ // value: '{{customer.trespass.witnessedBy.email}}'
323
+ // },
324
+ // {
325
+ // label: 'customer.trespass.witnessedBy.role',
326
+ // value: '{{customer.trespass.witnessedBy.role}}'
327
+ // },
328
+ // END customer object keys
329
+ ];
330
+
331
+
332
+
333
+ // key/values for map/match in preview
334
+ export const tokenValues = {
335
+
336
+ '{{declarationOfServiceIssuedBy}}': 'Brooks, Nicole',
337
+
338
+ // Incident level keys:
339
+ // '{{createdBy.firstName}}': 'Jane',
340
+ // '{{createdBy.lastName}}': 'Smith',
341
+ // '{{dateTimeOfIncident}}': `${todayDate}`,
342
+ // '{{detailedDescriptionOfIncident}}': 'Description of incident',
343
+ '{{formatLocation incident.incidentLocation}}': 'Central',
344
+ // '{{subLocation}}': 'Second floor',
345
+
346
+ '{{resolveIncTypes "incident.incidentTypes.description"}}': 'The incident type description',
347
+
348
+ '{{resolveIncTypes "incident.incidentTypes.title"}}': 'The incident type title',
349
+
350
+ // '{{incidentWitnesses.firstName}}': 'Joan',
351
+ // '{{incidentWitnesses.lastName}}': 'Smythe',
352
+ // '{{incidentWitnesses.barcode}}': '888085241068',
353
+ // '{{incidentWitnesses.phone}}': '509-444-5300',
354
+ // '{{incidentWitnesses.email}}': 'smythe.none@none.com',
355
+ // '{{incidentWitnesses.role}}': 'Security',
356
+
357
+ // START customer object keys
358
+ '{{resolve "customer.barcode"}}': '233233PBQ144144',
359
+ '{{resolve "customer.description"}}': 'a customer description',
360
+ '{{resolve "customer.details.city"}}': 'Spokane',
361
+ // '{{resolve "customer.details.descriptionOfCustomerAtOccurrence"}}': 'a customer description at occurrence',
362
+ '{{resolve "customer.details.eyes"}}': 'eye color',
363
+ '{{resolve "customer.details.hair"}}': 'hair color',
364
+ '{{resolve "customer.details.height"}}': 'customer height',
365
+ '{{resolve "customer.details.race"}}': 'customer race',
366
+ '{{resolve "customer.details.sex"}}': 'customer sex',
367
+ '{{resolve "customer.details.state"}}': 'Washington',
368
+ '{{resolve "customer.details.streetAddress"}}': '402 W Main Ave',
369
+ '{{resolve "customer.details.weight"}}': 'customer weight',
370
+ '{{resolve "customer.details.zipcode"}}': '99201',
371
+ '{{resolve "customer.firstName"}}': 'John',
372
+ '{{resolve "customer.lastName"}}': 'Smith',
373
+ '{{resolve "customer.fullName"}}': 'Smith, John',
374
+
375
+ '{{formatDate (resolve "customer.trespass.dateOfOccurrence")}}': `${todayDate}`,
376
+
377
+ '{{formatDate (resolve "customer.trespass.declarationOfService.date")}}': `${todayDate}`,
378
+ '{{formatLocation customer.trespass.declarationOfService.placeSigned}}': 'Central',
379
+ '{{resolve "customer.trespass.declarationOfService.signature"}}': 'true',
380
+ '{{resolve "customer.trespass.declarationOfService.title"}}': 'Manager name and title',
381
+
382
+ '{{{trespassDescriptionPlain}}}': 'Description of occurrence',
383
+
384
+ '{{formatDate (resolve "customer.trespass.endDateOfTrespass")}}': `${twoWeeksFromTodayDate}`,
385
+ // '{{resolve "customer.trespass.exclusionOrTrespassBasedOn"}}': 'Customer behavior',
386
+ '{{resolveTrespassReasons customer.trespass.exclusionOrTrespassBasedOn}}': 'Customer behavior',
387
+ '{{resolve "customer.trespass.witnessedBy" property="firstName"}}': 'Joan',
388
+ '{{resolve "customer.trespass.witnessedBy" property="lastName"}}': 'Smythe',
389
+ '{{resolve "customer.trespass.witnessedBy" property="fullName"}}': 'Smythe, Joan',
390
+ '{{resolve "customer.trespass.witnessedBy" property="barcode"}}': '888085241068',
391
+ '{{resolve "customer.trespass.witnessedBy" property="phone"}}': '509-444-5300',
392
+ '{{resolve "customer.trespass.witnessedBy" property="email"}}': 'smythe.none@none.com',
393
+ '{{resolve "customer.trespass.witnessedBy" property="role"}}': 'Security',
394
+ // END customer object keys
395
+ };
396
+
@@ -0,0 +1,18 @@
1
+ /*
2
+ -sort for ascending alphabetical order
3
+ @param {Array} locationsInServiceArray - array containing opted-in locations for service
4
+ @returns {Array} reference of location objects sorted in alphabetical order by their 'location' key value
5
+ */
6
+ const alphabetize = (locationsInServiceArray) => {
7
+ const sorted = locationsInServiceArray.sort((a, b) => {
8
+ if (a.location < b.location) {
9
+ return -1;
10
+ }
11
+ if (a.location > b.location) {
12
+ return 1;
13
+ }
14
+ return 0;
15
+ });
16
+ return sorted;
17
+ }
18
+ export default alphabetize;
@@ -0,0 +1,13 @@
1
+ /*
2
+ -get category title by id for associated key rendering
3
+ @param {Array} categoriesList - array of categories
4
+ @param {str} catId - string of the category id
5
+ @returns {str} - if match, returns str of the category title, else returns str 'Unknown category'
6
+ */
7
+ const getCategoryTitleById = (categoriesList, catId) => {
8
+ if (!Array.isArray(categoriesList) || !catId) return '';
9
+ const category = categoriesList.find(cat => cat.id === catId);
10
+ return category ? category.title : 'Unknown category';
11
+ };
12
+
13
+ export default getCategoryTitleById;
@@ -0,0 +1,15 @@
1
+ /*
2
+ -transform name or title to ID
3
+ -@example: "Yasuhara Middle School" --> "yasuhara-middle-school"
4
+ -@example: "1.1 Failure to comply" --> "1-1-failure-to-comply"
5
+ @param {String} name or title relating to obj
6
+ @returns {string} ID based on name or title to lowercase and delimited by replacing any non a-z, 0-9 characters with hyphen (no non-alpha/num chars) and trimmed for no preceding or hanging hyphens. this new string is used as an id for that related obj
7
+ */
8
+ const makeId = (string) => {
9
+ const replaceSpace = string.replace(/[^A-Za-z0-9]+/g, '-');
10
+ const lower_case = replaceSpace.toLowerCase();
11
+ const trimmed = lower_case.replace(/^-+|-+$/g, '');
12
+ return trimmed;
13
+ };
14
+
15
+ export default makeId;
@@ -0,0 +1,48 @@
1
+ import React from 'react';
2
+ import { FormattedMessage } from 'react-intl';
3
+ import { Settings } from '@folio/stripes/smart-components';
4
+ import IncidentCategoriesPane from './IncidentCategoriesPane';
5
+ import IncidentTypesPaneset from './IncidentTypesPaneset';
6
+ import LocationsPaneset from './LocationsPaneset';
7
+ import TrespassDocPaneset from './TrespassDocPaneset';
8
+ import TrespassReasonsPaneset from './TrespassReasonsPaneset';
9
+
10
+ export default class SecurityIncidentSettings extends React.Component {
11
+ pages = [
12
+ {
13
+ route: 'categories',
14
+ label: <FormattedMessage id="settings.categories" />,
15
+ component: (props) => <IncidentCategoriesPane {...props} />,
16
+ },
17
+ {
18
+ route: 'types',
19
+ label: <FormattedMessage id="settings.incident-types" />,
20
+ component: (props) => <IncidentTypesPaneset {...props} />,
21
+ },
22
+ {
23
+ route: 'locations',
24
+ label: <FormattedMessage id="settings.locations" />,
25
+ component: (props) => <LocationsPaneset {...props} />,
26
+ },
27
+ {
28
+ route: 'trespass-template',
29
+ label: <FormattedMessage id="settings.trespass-document-template" />,
30
+ component: (props) => <TrespassDocPaneset {...props} />,
31
+ },
32
+ {
33
+ route: 'trespass-reasons',
34
+ label: <FormattedMessage id="settings.trespass-reasons" />,
35
+ component: (props) => <TrespassReasonsPaneset {...props} />,
36
+ }
37
+ ];
38
+
39
+ render() {
40
+ return (
41
+ <Settings
42
+ {...this.props}
43
+ pages={this.pages}
44
+ paneTitle={<FormattedMessage id="settings.label" />}
45
+ />
46
+ );
47
+ }
48
+ }
@@ -0,0 +1,10 @@
1
+ module.exports = {
2
+ okapi: {
3
+ "url": "https://spokane-test-okapi.folio.indexdata.com",
4
+ "tenant": "spokane"
5
+ },
6
+ modules: {
7
+ "@spokane-folio/security-incident": {},
8
+ "@folio/users": {}
9
+ }
10
+ };
@@ -0,0 +1,8 @@
1
+ import './stripesConfig.mock';
2
+ import './stripesCore.mock';
3
+ import './stripes.mock';
4
+ import './intl.mock';
5
+ import './stripesIcon.mock';
6
+ import './stripesComponents.mock';
7
+ import './stripesSmartComponents.mock';
8
+ import './stripesUtils.mock';
@@ -0,0 +1,27 @@
1
+ import React from 'react';
2
+
3
+ jest.mock('react-intl', () => {
4
+ const intl = {
5
+ formatMessage: ({ id }) => id,
6
+ };
7
+
8
+ return {
9
+ ...jest.requireActual('react-intl'),
10
+ FormattedMessage: jest.fn(({ id, children }) => {
11
+ if (children) {
12
+ return children([id]);
13
+ }
14
+
15
+ return id;
16
+ }),
17
+ FormattedTime: jest.fn(({ value, children }) => {
18
+ if (children) {
19
+ return children([value]);
20
+ }
21
+
22
+ return value;
23
+ }),
24
+ useIntl: () => intl,
25
+ injectIntl: (Component) => (props) => <Component {...props} intl={intl} />,
26
+ };
27
+ });
@@ -0,0 +1,26 @@
1
+ import { noop } from 'lodash';
2
+
3
+ const buildStripes = (otherProperties = {}) => ({
4
+ hasPerm: noop,
5
+ hasInterface: noop,
6
+ clone: noop,
7
+ logger: { log: noop },
8
+ config: {},
9
+ okapi: {
10
+ url: '',
11
+ tenant: '',
12
+ },
13
+ locale: 'en-US',
14
+ withOkapi: true,
15
+ setToken: noop,
16
+ actionNames: [],
17
+ setLocale: noop,
18
+ setTimezone: noop,
19
+ setCurrency: noop,
20
+ setSinglePlugin: noop,
21
+ setBindings: noop,
22
+ connect: noop,
23
+ ...otherProperties,
24
+ });
25
+
26
+ export default buildStripes;