@esri/solution-common 4.1.2 → 5.0.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.
Files changed (261) hide show
  1. package/dist/cjs/completeItem.d.ts +29 -29
  2. package/dist/cjs/completeItem.js +81 -81
  3. package/dist/cjs/create-hub-request-options.d.ts +29 -29
  4. package/dist/cjs/create-hub-request-options.js +63 -63
  5. package/dist/cjs/deleteHelpers/deleteEmptyGroups.d.ts +24 -24
  6. package/dist/cjs/deleteHelpers/deleteEmptyGroups.js +41 -41
  7. package/dist/cjs/deleteHelpers/deleteGroupIfEmpty.d.ts +27 -27
  8. package/dist/cjs/deleteHelpers/deleteGroupIfEmpty.js +96 -96
  9. package/dist/cjs/deleteHelpers/deleteSolutionContents.d.ts +38 -38
  10. package/dist/cjs/deleteHelpers/deleteSolutionContents.js +129 -129
  11. package/dist/cjs/deleteHelpers/deleteSolutionFolder.d.ts +29 -29
  12. package/dist/cjs/deleteHelpers/deleteSolutionFolder.js +78 -78
  13. package/dist/cjs/deleteHelpers/deleteSolutionItem.d.ts +30 -30
  14. package/dist/cjs/deleteHelpers/deleteSolutionItem.js +53 -53
  15. package/dist/cjs/deleteHelpers/index.d.ts +22 -22
  16. package/dist/cjs/deleteHelpers/index.js +25 -25
  17. package/dist/cjs/deleteHelpers/reconstructBuildOrderIds.d.ts +27 -27
  18. package/dist/cjs/deleteHelpers/reconstructBuildOrderIds.js +33 -33
  19. package/dist/cjs/deleteHelpers/removeItems.d.ts +34 -34
  20. package/dist/cjs/deleteHelpers/removeItems.js +111 -111
  21. package/dist/cjs/deleteHelpers/reportProgress.d.ts +27 -27
  22. package/dist/cjs/deleteHelpers/reportProgress.js +45 -45
  23. package/dist/cjs/deleteSolution.d.ts +55 -55
  24. package/dist/cjs/deleteSolution.js +106 -106
  25. package/dist/cjs/dependencies.d.ts +26 -26
  26. package/dist/cjs/dependencies.js +170 -170
  27. package/dist/cjs/featureServiceHelpers.d.ts +791 -791
  28. package/dist/cjs/featureServiceHelpers.js +2420 -2420
  29. package/dist/cjs/generalHelpers.d.ts +392 -385
  30. package/dist/cjs/generalHelpers.js +857 -854
  31. package/dist/cjs/generalHelpers.js.map +1 -1
  32. package/dist/cjs/get-subscription-info.d.ts +27 -27
  33. package/dist/cjs/get-subscription-info.js +38 -38
  34. package/dist/cjs/getDeletableSolutionInfo.d.ts +29 -29
  35. package/dist/cjs/getDeletableSolutionInfo.js +52 -52
  36. package/dist/cjs/getItemTypeAbbrev.d.ts +19 -19
  37. package/dist/cjs/getItemTypeAbbrev.js +184 -184
  38. package/dist/cjs/getSolutionSummary.d.ts +27 -27
  39. package/dist/cjs/getSolutionSummary.js +100 -100
  40. package/dist/cjs/index.d.ts +43 -44
  41. package/dist/cjs/index.js +46 -47
  42. package/dist/cjs/index.js.map +1 -1
  43. package/dist/cjs/interfaces.d.ts +1334 -1334
  44. package/dist/cjs/interfaces.js +74 -74
  45. package/dist/cjs/interfaces.js.map +1 -1
  46. package/dist/cjs/libConnectors.d.ts +73 -73
  47. package/dist/cjs/libConnectors.js +114 -114
  48. package/dist/cjs/migrations/apply-schema.d.ts +24 -24
  49. package/dist/cjs/migrations/apply-schema.js +35 -35
  50. package/dist/cjs/migrations/is-legacy-solution.d.ts +24 -24
  51. package/dist/cjs/migrations/is-legacy-solution.js +39 -39
  52. package/dist/cjs/migrations/upgrade-three-dot-one.d.ts +27 -27
  53. package/dist/cjs/migrations/upgrade-three-dot-one.js +48 -48
  54. package/dist/cjs/migrations/upgrade-three-dot-zero.d.ts +27 -27
  55. package/dist/cjs/migrations/upgrade-three-dot-zero.js +42 -42
  56. package/dist/cjs/migrations/upgrade-two-dot-five.d.ts +24 -24
  57. package/dist/cjs/migrations/upgrade-two-dot-five.js +72 -72
  58. package/dist/cjs/migrations/upgrade-two-dot-four.d.ts +24 -24
  59. package/dist/cjs/migrations/upgrade-two-dot-four.js +71 -71
  60. package/dist/cjs/migrations/upgrade-two-dot-one.d.ts +7 -7
  61. package/dist/cjs/migrations/upgrade-two-dot-one.js +38 -38
  62. package/dist/cjs/migrations/upgrade-two-dot-seven.d.ts +23 -23
  63. package/dist/cjs/migrations/upgrade-two-dot-seven.js +57 -57
  64. package/dist/cjs/migrations/upgrade-two-dot-six.d.ts +27 -27
  65. package/dist/cjs/migrations/upgrade-two-dot-six.js +60 -60
  66. package/dist/cjs/migrations/upgrade-two-dot-three.d.ts +23 -23
  67. package/dist/cjs/migrations/upgrade-two-dot-three.js +54 -54
  68. package/dist/cjs/migrations/upgrade-two-dot-two.d.ts +23 -23
  69. package/dist/cjs/migrations/upgrade-two-dot-two.js +57 -57
  70. package/dist/cjs/migrations/upgrade-two-dot-zero.d.ts +44 -44
  71. package/dist/cjs/migrations/upgrade-two-dot-zero.js +94 -94
  72. package/dist/cjs/migrator.d.ts +25 -25
  73. package/dist/cjs/migrator.js +76 -76
  74. package/dist/cjs/resourceHelpers.d.ts +191 -191
  75. package/dist/cjs/resourceHelpers.js +383 -390
  76. package/dist/cjs/resourceHelpers.js.map +1 -1
  77. package/dist/cjs/resources/add-resource-from-blob.d.ts +26 -26
  78. package/dist/cjs/resources/add-resource-from-blob.js +51 -51
  79. package/dist/cjs/resources/addMetadataFromBlob.d.ts +25 -25
  80. package/dist/cjs/resources/addMetadataFromBlob.js +42 -42
  81. package/dist/cjs/resources/convert-item-resource-to-storage-resource.d.ts +32 -32
  82. package/dist/cjs/resources/convert-item-resource-to-storage-resource.js +69 -69
  83. package/dist/cjs/resources/convert-storage-resource-to-item-resource.d.ts +29 -29
  84. package/dist/cjs/resources/convert-storage-resource-to-item-resource.js +69 -69
  85. package/dist/cjs/resources/copyAssociatedFiles.d.ts +67 -67
  86. package/dist/cjs/resources/copyAssociatedFiles.js +301 -301
  87. package/dist/cjs/resources/copyDataIntoItem.d.ts +33 -33
  88. package/dist/cjs/resources/copyDataIntoItem.js +61 -62
  89. package/dist/cjs/resources/copyDataIntoItem.js.map +1 -1
  90. package/dist/cjs/resources/copyMetadataIntoItem.d.ts +26 -26
  91. package/dist/cjs/resources/copyMetadataIntoItem.js +45 -45
  92. package/dist/cjs/resources/copyResourceIntoZip.d.ts +33 -33
  93. package/dist/cjs/resources/copyResourceIntoZip.js +77 -77
  94. package/dist/cjs/resources/copyZipIntoItem.d.ts +25 -25
  95. package/dist/cjs/resources/copyZipIntoItem.js +53 -53
  96. package/dist/cjs/resources/createCopyResults.d.ts +25 -25
  97. package/dist/cjs/resources/createCopyResults.js +35 -35
  98. package/dist/cjs/resources/get-blob.d.ts +26 -26
  99. package/dist/cjs/resources/get-blob.js +26 -26
  100. package/dist/cjs/resources/getItemResourcesFilesFromPaths.d.ts +24 -24
  101. package/dist/cjs/resources/getItemResourcesFilesFromPaths.js +48 -48
  102. package/dist/cjs/resources/getItemResourcesPaths.d.ts +26 -26
  103. package/dist/cjs/resources/getItemResourcesPaths.js +72 -72
  104. package/dist/cjs/resources/index.d.ts +29 -29
  105. package/dist/cjs/resources/index.js +32 -32
  106. package/dist/cjs/resources/solution-resource.d.ts +35 -35
  107. package/dist/cjs/resources/solution-resource.js +30 -30
  108. package/dist/cjs/resources/solution-resource.js.map +1 -1
  109. package/dist/cjs/resources/transform-resource-paths-to-solution-resources.d.ts +56 -56
  110. package/dist/cjs/resources/transform-resource-paths-to-solution-resources.js +145 -145
  111. package/dist/cjs/restHelpers.d.ts +586 -585
  112. package/dist/cjs/restHelpers.js +1888 -1883
  113. package/dist/cjs/restHelpers.js.map +1 -1
  114. package/dist/cjs/restHelpersGet.d.ts +288 -288
  115. package/dist/cjs/restHelpersGet.js +803 -803
  116. package/dist/cjs/sharing/index.d.ts +16 -16
  117. package/dist/cjs/sharing/index.js +19 -19
  118. package/dist/cjs/sharing/share-item-to-groups.d.ts +26 -26
  119. package/dist/cjs/sharing/share-item-to-groups.js +43 -43
  120. package/dist/cjs/templatization.d.ts +139 -139
  121. package/dist/cjs/templatization.js +313 -313
  122. package/dist/cjs/trackingHelpers.d.ts +116 -116
  123. package/dist/cjs/trackingHelpers.js +216 -216
  124. package/dist/cjs/velocityHelpers.d.ts +57 -57
  125. package/dist/cjs/velocityHelpers.js +134 -134
  126. package/dist/cjs/workforceHelpers.d.ts +115 -115
  127. package/dist/cjs/workforceHelpers.js +746 -746
  128. package/dist/cjs/workforceHelpers.js.map +1 -1
  129. package/dist/esm/completeItem.d.ts +29 -29
  130. package/dist/esm/completeItem.js +76 -76
  131. package/dist/esm/create-hub-request-options.d.ts +29 -29
  132. package/dist/esm/create-hub-request-options.js +59 -59
  133. package/dist/esm/deleteHelpers/deleteEmptyGroups.d.ts +24 -24
  134. package/dist/esm/deleteHelpers/deleteEmptyGroups.js +37 -37
  135. package/dist/esm/deleteHelpers/deleteGroupIfEmpty.d.ts +27 -27
  136. package/dist/esm/deleteHelpers/deleteGroupIfEmpty.js +91 -91
  137. package/dist/esm/deleteHelpers/deleteSolutionContents.d.ts +38 -38
  138. package/dist/esm/deleteHelpers/deleteSolutionContents.js +124 -124
  139. package/dist/esm/deleteHelpers/deleteSolutionFolder.d.ts +29 -29
  140. package/dist/esm/deleteHelpers/deleteSolutionFolder.js +73 -73
  141. package/dist/esm/deleteHelpers/deleteSolutionItem.d.ts +30 -30
  142. package/dist/esm/deleteHelpers/deleteSolutionItem.js +48 -48
  143. package/dist/esm/deleteHelpers/index.d.ts +22 -22
  144. package/dist/esm/deleteHelpers/index.js +22 -22
  145. package/dist/esm/deleteHelpers/reconstructBuildOrderIds.d.ts +27 -27
  146. package/dist/esm/deleteHelpers/reconstructBuildOrderIds.js +28 -28
  147. package/dist/esm/deleteHelpers/removeItems.d.ts +34 -34
  148. package/dist/esm/deleteHelpers/removeItems.js +106 -106
  149. package/dist/esm/deleteHelpers/reportProgress.d.ts +27 -27
  150. package/dist/esm/deleteHelpers/reportProgress.js +41 -41
  151. package/dist/esm/deleteSolution.d.ts +55 -55
  152. package/dist/esm/deleteSolution.js +100 -100
  153. package/dist/esm/dependencies.d.ts +26 -26
  154. package/dist/esm/dependencies.js +166 -166
  155. package/dist/esm/featureServiceHelpers.d.ts +791 -791
  156. package/dist/esm/featureServiceHelpers.js +2336 -2336
  157. package/dist/esm/generalHelpers.d.ts +392 -385
  158. package/dist/esm/generalHelpers.js +810 -808
  159. package/dist/esm/generalHelpers.js.map +1 -1
  160. package/dist/esm/get-subscription-info.d.ts +27 -27
  161. package/dist/esm/get-subscription-info.js +34 -34
  162. package/dist/esm/getDeletableSolutionInfo.d.ts +29 -29
  163. package/dist/esm/getDeletableSolutionInfo.js +47 -47
  164. package/dist/esm/getItemTypeAbbrev.d.ts +19 -19
  165. package/dist/esm/getItemTypeAbbrev.js +180 -180
  166. package/dist/esm/getSolutionSummary.d.ts +27 -27
  167. package/dist/esm/getSolutionSummary.js +95 -95
  168. package/dist/esm/index.d.ts +43 -44
  169. package/dist/esm/index.js +43 -44
  170. package/dist/esm/index.js.map +1 -1
  171. package/dist/esm/interfaces.d.ts +1334 -1334
  172. package/dist/esm/interfaces.js +70 -70
  173. package/dist/esm/libConnectors.d.ts +73 -73
  174. package/dist/esm/libConnectors.js +104 -104
  175. package/dist/esm/migrations/apply-schema.d.ts +24 -24
  176. package/dist/esm/migrations/apply-schema.js +31 -31
  177. package/dist/esm/migrations/is-legacy-solution.d.ts +24 -24
  178. package/dist/esm/migrations/is-legacy-solution.js +35 -35
  179. package/dist/esm/migrations/upgrade-three-dot-one.d.ts +27 -27
  180. package/dist/esm/migrations/upgrade-three-dot-one.js +44 -44
  181. package/dist/esm/migrations/upgrade-three-dot-zero.d.ts +27 -27
  182. package/dist/esm/migrations/upgrade-three-dot-zero.js +38 -38
  183. package/dist/esm/migrations/upgrade-two-dot-five.d.ts +24 -24
  184. package/dist/esm/migrations/upgrade-two-dot-five.js +68 -68
  185. package/dist/esm/migrations/upgrade-two-dot-four.d.ts +24 -24
  186. package/dist/esm/migrations/upgrade-two-dot-four.js +67 -67
  187. package/dist/esm/migrations/upgrade-two-dot-one.d.ts +7 -7
  188. package/dist/esm/migrations/upgrade-two-dot-one.js +34 -34
  189. package/dist/esm/migrations/upgrade-two-dot-seven.d.ts +23 -23
  190. package/dist/esm/migrations/upgrade-two-dot-seven.js +53 -53
  191. package/dist/esm/migrations/upgrade-two-dot-six.d.ts +27 -27
  192. package/dist/esm/migrations/upgrade-two-dot-six.js +56 -56
  193. package/dist/esm/migrations/upgrade-two-dot-three.d.ts +23 -23
  194. package/dist/esm/migrations/upgrade-two-dot-three.js +50 -50
  195. package/dist/esm/migrations/upgrade-two-dot-two.d.ts +23 -23
  196. package/dist/esm/migrations/upgrade-two-dot-two.js +53 -53
  197. package/dist/esm/migrations/upgrade-two-dot-zero.d.ts +44 -44
  198. package/dist/esm/migrations/upgrade-two-dot-zero.js +87 -87
  199. package/dist/esm/migrator.d.ts +25 -25
  200. package/dist/esm/migrator.js +72 -72
  201. package/dist/esm/resourceHelpers.d.ts +191 -191
  202. package/dist/esm/resourceHelpers.js +364 -371
  203. package/dist/esm/resourceHelpers.js.map +1 -1
  204. package/dist/esm/resources/add-resource-from-blob.d.ts +26 -26
  205. package/dist/esm/resources/add-resource-from-blob.js +47 -47
  206. package/dist/esm/resources/addMetadataFromBlob.d.ts +25 -25
  207. package/dist/esm/resources/addMetadataFromBlob.js +38 -38
  208. package/dist/esm/resources/convert-item-resource-to-storage-resource.d.ts +32 -32
  209. package/dist/esm/resources/convert-item-resource-to-storage-resource.js +65 -65
  210. package/dist/esm/resources/convert-storage-resource-to-item-resource.d.ts +29 -29
  211. package/dist/esm/resources/convert-storage-resource-to-item-resource.js +65 -65
  212. package/dist/esm/resources/copyAssociatedFiles.d.ts +67 -67
  213. package/dist/esm/resources/copyAssociatedFiles.js +293 -293
  214. package/dist/esm/resources/copyDataIntoItem.d.ts +33 -33
  215. package/dist/esm/resources/copyDataIntoItem.js +56 -57
  216. package/dist/esm/resources/copyDataIntoItem.js.map +1 -1
  217. package/dist/esm/resources/copyMetadataIntoItem.d.ts +26 -26
  218. package/dist/esm/resources/copyMetadataIntoItem.js +41 -41
  219. package/dist/esm/resources/copyResourceIntoZip.d.ts +33 -33
  220. package/dist/esm/resources/copyResourceIntoZip.js +72 -72
  221. package/dist/esm/resources/copyZipIntoItem.d.ts +25 -25
  222. package/dist/esm/resources/copyZipIntoItem.js +49 -49
  223. package/dist/esm/resources/createCopyResults.d.ts +25 -25
  224. package/dist/esm/resources/createCopyResults.js +31 -31
  225. package/dist/esm/resources/get-blob.d.ts +26 -26
  226. package/dist/esm/resources/get-blob.js +22 -22
  227. package/dist/esm/resources/getItemResourcesFilesFromPaths.d.ts +24 -24
  228. package/dist/esm/resources/getItemResourcesFilesFromPaths.js +44 -44
  229. package/dist/esm/resources/getItemResourcesPaths.d.ts +26 -26
  230. package/dist/esm/resources/getItemResourcesPaths.js +68 -68
  231. package/dist/esm/resources/index.d.ts +29 -29
  232. package/dist/esm/resources/index.js +29 -29
  233. package/dist/esm/resources/solution-resource.d.ts +35 -35
  234. package/dist/esm/resources/solution-resource.js +27 -27
  235. package/dist/esm/resources/transform-resource-paths-to-solution-resources.d.ts +56 -56
  236. package/dist/esm/resources/transform-resource-paths-to-solution-resources.js +137 -137
  237. package/dist/esm/restHelpers.d.ts +586 -585
  238. package/dist/esm/restHelpers.js +1827 -1823
  239. package/dist/esm/restHelpers.js.map +1 -1
  240. package/dist/esm/restHelpersGet.d.ts +288 -288
  241. package/dist/esm/restHelpersGet.js +763 -763
  242. package/dist/esm/sharing/index.d.ts +16 -16
  243. package/dist/esm/sharing/index.js +16 -16
  244. package/dist/esm/sharing/share-item-to-groups.d.ts +26 -26
  245. package/dist/esm/sharing/share-item-to-groups.js +39 -39
  246. package/dist/esm/templatization.d.ts +139 -139
  247. package/dist/esm/templatization.js +293 -293
  248. package/dist/esm/trackingHelpers.d.ts +116 -116
  249. package/dist/esm/trackingHelpers.js +204 -204
  250. package/dist/esm/velocityHelpers.d.ts +57 -57
  251. package/dist/esm/velocityHelpers.js +128 -128
  252. package/dist/esm/workforceHelpers.d.ts +115 -115
  253. package/dist/esm/workforceHelpers.js +717 -717
  254. package/dist/esm/workforceHelpers.js.map +1 -1
  255. package/package.json +2 -2
  256. package/dist/cjs/polyfills.d.ts +0 -40
  257. package/dist/cjs/polyfills.js +0 -98
  258. package/dist/cjs/polyfills.js.map +0 -1
  259. package/dist/esm/polyfills.d.ts +0 -40
  260. package/dist/esm/polyfills.js +0 -93
  261. package/dist/esm/polyfills.js.map +0 -1
@@ -1,718 +1,718 @@
1
- /** @license
2
- * Copyright 2020 Esri
3
- *
4
- * Licensed under the Apache License, Version 2.0 (the "License");
5
- * you may not use this file except in compliance with the License.
6
- * You may obtain a copy of the License at
7
- *
8
- * http://www.apache.org/licenses/LICENSE-2.0
9
- *
10
- * Unless required by applicable law or agreed to in writing, software
11
- * distributed under the License is distributed on an "AS IS" BASIS,
12
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- * See the License for the specific language governing permissions and
14
- * limitations under the License.
15
- */
16
- /**
17
- * Provides general helper functions.
18
- *
19
- * @module workforceHelpers
20
- */
21
- import { applyEdits, queryFeatures } from "@esri/arcgis-rest-feature-layer";
22
- import { getIDs, getProp, fail, idTest, regExTest, setProp } from "./generalHelpers";
23
- import { rest_request } from "./restHelpers";
24
- import { templatizeTerm, replaceInTemplate } from "./templatization";
25
- import { cacheLayerInfo } from "./featureServiceHelpers";
26
- //#region workforce v1
27
- /**
28
- * Converts an workforce item to a template.
29
- *
30
- * @param itemTemplate template for the workforce project item
31
- * @param authentication credentials for any requests
32
- * @param templateDictionary Hash of key details used for variable replacement
33
- * @returns templatized itemTemplate
34
- */
35
- export function convertWorkforceItemToTemplate(itemTemplate, authentication, templateDictionary) {
36
- return new Promise((resolve, reject) => {
37
- // This function is specific to workforce v1 project structure
38
- // Key properties that contain item IDs for the workforce project type
39
- const keyProperties = getKeyWorkforceProperties(1);
40
- // The templates data to process
41
- const data = itemTemplate.data;
42
- if (data) {
43
- // Extract dependencies
44
- extractWorkforceDependencies(data, keyProperties, authentication).then(results => {
45
- itemTemplate.dependencies = results.dependencies;
46
- // templatize key properties
47
- itemTemplate.data = templatizeWorkforce(data, keyProperties, results.urlHash, templateDictionary);
48
- resolve(itemTemplate);
49
- }, e => reject(fail(e)));
50
- }
51
- else {
52
- resolve(itemTemplate);
53
- }
54
- });
55
- }
56
- /**
57
- * Gets the ids of the dependencies of the workforce project.
58
- *
59
- * @param data itemTemplate data
60
- * @param keyProperties workforce project properties that contain references to dependencies
61
- * @param authentication credentials for any requests
62
- * @returns List of dependencies ids
63
- */
64
- export function extractWorkforceDependencies(data, keyProperties, authentication) {
65
- return new Promise((resolve, reject) => {
66
- const deps = [];
67
- // get the ids for the service dependencies
68
- // "workerWebMapId" and "dispatcherWebMapId" are already IDs and don't have a serviceItemId
69
- keyProperties.forEach(p => {
70
- const serviceItemId = getProp(data, p + ".serviceItemId");
71
- const v = getProp(data, p);
72
- if (serviceItemId) {
73
- if (deps.indexOf(serviceItemId) === -1) {
74
- deps.push(serviceItemId);
75
- }
76
- }
77
- else {
78
- idTest(v, deps);
79
- }
80
- });
81
- if (getProp(data, "assignmentIntegrations")) {
82
- let requests = [];
83
- let urls = [];
84
- data.assignmentIntegrations.forEach((ai) => {
85
- if (ai.assignmentTypes) {
86
- const assignmentKeys = Object.keys(ai.assignmentTypes);
87
- assignmentKeys.forEach(k => {
88
- const urlTemplate = ai.assignmentTypes[k].urlTemplate;
89
- idTest(urlTemplate, deps);
90
- const serviceRequests = urlTest(urlTemplate, authentication);
91
- if (Array.isArray(serviceRequests.requests) &&
92
- serviceRequests.requests.length > 0) {
93
- requests = requests.concat(serviceRequests.requests);
94
- urls = urls.concat(serviceRequests.urls);
95
- }
96
- });
97
- }
98
- });
99
- if (requests.length > 0) {
100
- Promise.all(requests).then(results => {
101
- const urlHash = {};
102
- // Get the serviceItemId for the url
103
- /* istanbul ignore else */
104
- if (Array.isArray(results)) {
105
- results.forEach((result, i) => {
106
- /* istanbul ignore else */
107
- if (result.serviceItemId) {
108
- urlHash[urls[i]] = result.serviceItemId;
109
- /* istanbul ignore else */
110
- if (deps.indexOf(result.serviceItemId) === -1) {
111
- deps.push(result.serviceItemId);
112
- }
113
- }
114
- });
115
- }
116
- resolve({
117
- dependencies: deps,
118
- urlHash: urlHash
119
- });
120
- }, e => reject(fail(e)));
121
- }
122
- else {
123
- resolve({
124
- dependencies: deps,
125
- urlHash: {}
126
- });
127
- }
128
- }
129
- else {
130
- resolve({
131
- dependencies: deps,
132
- urlHash: {}
133
- });
134
- }
135
- });
136
- }
137
- /**
138
- * Templatizes key item properties.
139
- *
140
- * @param data itemTemplate data
141
- * @param keyProperties workforce project properties that should be templatized
142
- * @param urlHash a key value pair of url and itemId
143
- * @param templateDictionary Hash of key details used for variable replacement
144
- * @returns an updated data object to be stored in the template
145
- */
146
- export function templatizeWorkforce(data, keyProperties, urlHash, templateDictionary) {
147
- keyProperties.forEach(p => {
148
- /* istanbul ignore else */
149
- if (getProp(data, p)) {
150
- if (getProp(data[p], "serviceItemId")) {
151
- // templatize properties with id and url
152
- const id = data[p].serviceItemId;
153
- let serviceItemIdSuffix = ".itemId";
154
- /* istanbul ignore else */
155
- if (getProp(data[p], "url")) {
156
- const layerId = getLayerId(data[p].url);
157
- cacheLayerInfo(layerId, id, data[p].url, templateDictionary);
158
- data[p].url = templatizeTerm(id, id, getReplaceValue(layerId, ".url"));
159
- serviceItemIdSuffix = getReplaceValue(layerId, serviceItemIdSuffix);
160
- }
161
- data[p].serviceItemId = templatizeTerm(id, id, serviceItemIdSuffix);
162
- }
163
- else {
164
- // templatize simple id properties
165
- data[p] = templatizeTerm(data[p], data[p], ".itemId");
166
- }
167
- }
168
- });
169
- data["folderId"] = "{{folderId}}";
170
- // templatize app integrations
171
- const integrations = data.assignmentIntegrations || [];
172
- integrations.forEach(i => {
173
- _templatizeUrlTemplate(i, urlHash);
174
- /* istanbul ignore else */
175
- if (i.assignmentTypes) {
176
- const assignmentKeys = Object.keys(i.assignmentTypes);
177
- assignmentKeys.forEach(k => {
178
- _templatizeUrlTemplate(i.assignmentTypes[k], urlHash);
179
- });
180
- }
181
- });
182
- return data;
183
- }
184
- //#endregion
185
- /**
186
- * Evaluate key properties in the workforce service of additional items that are needed
187
- *
188
- * @param itemTemplate template for the workforce project item
189
- * @param dependencies list of the items dependencies
190
- * @returns an array of objects with dependency ids
191
- */
192
- export function getWorkforceDependencies(itemTemplate, dependencies) {
193
- const properties = itemTemplate.item.properties || {};
194
- const keyProperties = getKeyWorkforceProperties(2);
195
- dependencies = keyProperties.reduce(function (acc, v) {
196
- /* istanbul ignore else */
197
- if (properties[v] && dependencies.indexOf(properties[v]) < 0) {
198
- acc.push(properties[v]);
199
- }
200
- return acc;
201
- }, dependencies);
202
- // We also need the dependencies listed in the Assignment Integrations table
203
- const infos = getProp(itemTemplate, "properties.workforceInfos.assignmentIntegrationInfos");
204
- /* istanbul ignore else */
205
- if (infos && infos.length > 0) {
206
- infos.forEach((info) => {
207
- const infoKeys = Object.keys(info);
208
- /* istanbul ignore else */
209
- if (infoKeys.indexOf("dependencies") > -1) {
210
- info["dependencies"].forEach((d) => {
211
- /* istanbul ignore else */
212
- if (dependencies.indexOf(d) < 0) {
213
- dependencies.push(d);
214
- }
215
- });
216
- }
217
- });
218
- }
219
- return dependencies.map(d => {
220
- return { id: d, name: "" };
221
- });
222
- }
223
- export function getWorkforceServiceInfo(properties, url, authentication) {
224
- return new Promise((resolve, reject) => {
225
- url = url.replace("/rest/admin/services", "/rest/services");
226
- url = _updateUrl(url);
227
- const requests = [
228
- queryFeatures({
229
- url: `${url}3`,
230
- where: "1=1",
231
- authentication
232
- }),
233
- queryFeatures({
234
- url: `${url}4`,
235
- where: "1=1",
236
- authentication
237
- })
238
- ];
239
- Promise.all(requests).then(responses => {
240
- const [assignmentTypes, assignmentIntegrations] = responses;
241
- properties.workforceInfos = {
242
- assignmentTypeInfos: _getAssignmentTypeInfos(assignmentTypes)
243
- };
244
- _getAssignmentIntegrationInfos(assignmentIntegrations, authentication).then(results => {
245
- properties.workforceInfos["assignmentIntegrationInfos"] = results;
246
- _updateGlobalIdAndAssignmentType(properties.workforceInfos);
247
- resolve(properties);
248
- }, e => reject(fail(e)));
249
- }, e => reject(fail(e)));
250
- });
251
- }
252
- /**
253
- * Wrap global id and assignmenttype values in curly braces
254
- *
255
- * Added for issue #734
256
- *
257
- * This function will update the provided workforceInfos object
258
- *
259
- * @param workforceInfos the object that stores the integration and type info with global ids
260
- * @private
261
- */
262
- export function _updateGlobalIdAndAssignmentType(workforceInfos) {
263
- const updateId = (i) => {
264
- /* istanbul ignore else */
265
- if (i["GlobalID"]) {
266
- i["GlobalID"] = `{${i["GlobalID"]}}`;
267
- }
268
- /* istanbul ignore else */
269
- if (i["assignmenttype"]) {
270
- i["assignmenttype"] = `{${i["assignmenttype"]}}`;
271
- }
272
- return i;
273
- };
274
- const assignmentIntegrationInfos = getProp(workforceInfos, "assignmentIntegrationInfos");
275
- /* istanbul ignore else */
276
- if (assignmentIntegrationInfos && Array.isArray(assignmentIntegrationInfos)) {
277
- setProp(workforceInfos, "assignmentIntegrationInfos", assignmentIntegrationInfos.map(updateId));
278
- }
279
- const assignmentTypeInfos = getProp(workforceInfos, "assignmentTypeInfos");
280
- /* istanbul ignore else */
281
- if (assignmentTypeInfos && Array.isArray(assignmentTypeInfos)) {
282
- setProp(workforceInfos, "assignmentTypeInfos", assignmentTypeInfos.map(updateId));
283
- }
284
- }
285
- //???
286
- export function _getAssignmentTypeInfos(assignmentTypes) {
287
- // Assignment Types
288
- const assignmentTypeInfos = [];
289
- const keyAssignmentTypeProps = [
290
- "description",
291
- assignmentTypes.globalIdFieldName
292
- ];
293
- assignmentTypes.features.forEach((f) => {
294
- const info = {};
295
- keyAssignmentTypeProps.forEach(p => {
296
- info[p] = f.attributes[p];
297
- });
298
- assignmentTypeInfos.push(info);
299
- });
300
- return assignmentTypeInfos;
301
- }
302
- //???
303
- export function _getAssignmentIntegrationInfos(assignmentIntegrations, authentication) {
304
- return new Promise((resolve, reject) => {
305
- let requests = [];
306
- let urls = [];
307
- const assignmentIntegrationInfos = [];
308
- const keyAssignmentIntegrationsProps = [
309
- "appid",
310
- assignmentIntegrations.globalIdFieldName,
311
- "prompt",
312
- "urltemplate",
313
- "assignmenttype"
314
- ];
315
- assignmentIntegrations.features.forEach((f) => {
316
- const info = {};
317
- keyAssignmentIntegrationsProps.forEach(p => {
318
- info[p] = f.attributes[p];
319
- /* istanbul ignore else */
320
- if (p === "urltemplate") {
321
- const urlTemplate = f.attributes[p];
322
- const ids = getIDs(urlTemplate);
323
- info["dependencies"] = ids;
324
- const serviceRequests = urlTest(urlTemplate, authentication);
325
- /* istanbul ignore else */
326
- if (Array.isArray(serviceRequests.requests) &&
327
- serviceRequests.requests.length > 0) {
328
- requests = requests.concat(serviceRequests.requests);
329
- urls = urls.concat(serviceRequests.urls);
330
- }
331
- }
332
- });
333
- assignmentIntegrationInfos.push(info);
334
- });
335
- getUrlDependencies(requests, urls).then(results => {
336
- assignmentIntegrationInfos.forEach(ai => {
337
- _templatizeUrlTemplate(ai, results.urlHash);
338
- });
339
- resolve(assignmentIntegrationInfos);
340
- }, e => reject(fail(e)));
341
- });
342
- }
343
- export function getUrlDependencies(requests, urls) {
344
- return new Promise((resolve, reject) => {
345
- const dependencies = [];
346
- if (requests.length > 0) {
347
- Promise.all(requests).then(results => {
348
- const urlHash = {};
349
- // Get the serviceItemId for the url
350
- /* istanbul ignore else */
351
- if (Array.isArray(results)) {
352
- results.forEach((result, i) => {
353
- /* istanbul ignore else */
354
- if (result.serviceItemId) {
355
- urlHash[urls[i]] = result.serviceItemId;
356
- /* istanbul ignore else */
357
- if (dependencies.indexOf(result.serviceItemId) === -1) {
358
- dependencies.push(result.serviceItemId);
359
- }
360
- }
361
- });
362
- }
363
- resolve({
364
- dependencies,
365
- urlHash
366
- });
367
- }, e => reject(fail(e)));
368
- }
369
- else {
370
- resolve({
371
- dependencies,
372
- urlHash: {}
373
- });
374
- }
375
- });
376
- }
377
- /**
378
- * Templatizes values from a urlTemplate
379
- *
380
- * @param item the object that may contain a urlTemplate
381
- * @param urlHash a key value pair of url and itemId
382
- * @private
383
- */
384
- export function _templatizeUrlTemplate(item, urlHash) {
385
- // v1 uses urlTemplate
386
- // v2 uses urltemplate
387
- const urlTemplateVar = getProp(item, "urlTemplate")
388
- ? "urlTemplate"
389
- : "urltemplate";
390
- let urlTemplate = getProp(item, urlTemplateVar);
391
- /* istanbul ignore else */
392
- if (urlTemplate) {
393
- const ids = getIDs(urlTemplate);
394
- ids.forEach(id => {
395
- urlTemplate = urlTemplate.replace(id, templatizeTerm(id, id, ".itemId"));
396
- });
397
- const urls = _getURLs(urlTemplate);
398
- urls.forEach(url => {
399
- const layerId = getLayerId(url);
400
- const replaceValue = getReplaceValue(layerId, ".url");
401
- const id = urlHash[url];
402
- /* istanbul ignore else */
403
- if (Array.isArray(item.dependencies) &&
404
- item.dependencies.indexOf(id) < 0) {
405
- item.dependencies.push(id);
406
- }
407
- urlTemplate = urlTemplate.replace(url, templatizeTerm(id, id, replaceValue));
408
- });
409
- setProp(item, urlTemplateVar, urlTemplate);
410
- }
411
- }
412
- export function getLayerId(url) {
413
- return url.indexOf("FeatureServer/") > -1
414
- ? url.substr(url.lastIndexOf("/") + 1)
415
- : undefined;
416
- }
417
- export function getReplaceValue(layerId, suffix) {
418
- return isNaN(Number.parseInt(layerId, 10))
419
- ? `${suffix}`
420
- : `.layer${layerId}${suffix}`;
421
- }
422
- export function postProcessWorkforceTemplates(templates) {
423
- const groupUpdates = {};
424
- const _templates = templates.map(t => {
425
- // templatize Workforce Project
426
- t = _templatizeWorkforceProject(t, groupUpdates);
427
- // templatize Workforce Dispatcher
428
- t = _templatizeWorkforceDispatcherOrWorker(t, "Workforce Dispatcher");
429
- // templatize Workforce Worker
430
- t = _templatizeWorkforceDispatcherOrWorker(t, "Workforce Worker");
431
- return t;
432
- });
433
- return _templates.map(t => {
434
- if (groupUpdates[t.itemId]) {
435
- t.dependencies = t.dependencies.concat(groupUpdates[t.itemId]);
436
- }
437
- return t;
438
- });
439
- }
440
- //???
441
- export function _templatizeWorkforceProject(t, groupUpdates) {
442
- /* istanbul ignore else */
443
- if (isWorkforceProject(t)) {
444
- const properties = t.item.properties || {};
445
- const keyProperties = getKeyWorkforceProperties(2);
446
- const groupId = properties["workforceProjectGroupId"];
447
- const shuffleIds = [];
448
- Object.keys(properties).forEach((p) => {
449
- /* istanbul ignore else */
450
- if (keyProperties.indexOf(p) > -1) {
451
- const id = properties[p];
452
- /* istanbul ignore else */
453
- if (id !== groupId) {
454
- shuffleIds.push(id);
455
- }
456
- t.item.properties[p] = templatizeTerm(properties[p], properties[p], ".itemId");
457
- }
458
- });
459
- // update the dependencies
460
- t.dependencies = t.dependencies.filter((d) => d !== groupId && shuffleIds.indexOf(d) < 0);
461
- // shuffle and cleanup
462
- const workforceInfos = getProp(t, "properties.workforceInfos");
463
- /* istanbul ignore else */
464
- if (workforceInfos) {
465
- Object.keys(workforceInfos).forEach(k => {
466
- workforceInfos[k].forEach((wInfo) => {
467
- /* istanbul ignore else */
468
- if (wInfo.dependencies) {
469
- wInfo.dependencies.forEach((id) => {
470
- /* istanbul ignore else */
471
- if (shuffleIds.indexOf(id) < 0) {
472
- shuffleIds.push(id);
473
- }
474
- const depIndex = t.dependencies.indexOf(id);
475
- /* istanbul ignore else */
476
- if (depIndex > -1) {
477
- t.dependencies.splice(depIndex, 1);
478
- }
479
- });
480
- delete wInfo.dependencies;
481
- }
482
- });
483
- });
484
- }
485
- // move the dependencies to the group
486
- groupUpdates[groupId] = shuffleIds;
487
- }
488
- return t;
489
- }
490
- //???
491
- export function _templatizeWorkforceDispatcherOrWorker(t, type) {
492
- /* istanbul ignore else */
493
- if ((t.item.typeKeywords || []).indexOf(type) > -1) {
494
- const properties = t.item.properties || {};
495
- const fsId = properties["workforceFeatureServiceId"];
496
- /* istanbul ignore else */
497
- if (fsId) {
498
- t.item.properties["workforceFeatureServiceId"] = templatizeTerm(fsId, fsId, ".itemId");
499
- }
500
- }
501
- return t;
502
- }
503
- // Helpers
504
- export function isWorkforceProject(itemTemplate) {
505
- return ((itemTemplate.item.typeKeywords || []).indexOf("Workforce Project") > -1);
506
- }
507
- export function getKeyWorkforceProperties(version) {
508
- return version === 1
509
- ? [
510
- "groupId",
511
- "workerWebMapId",
512
- "dispatcherWebMapId",
513
- "dispatchers",
514
- "assignments",
515
- "workers",
516
- "tracks"
517
- ]
518
- : [
519
- "workforceDispatcherMapId",
520
- "workforceProjectGroupId",
521
- "workforceWorkerMapId"
522
- ];
523
- }
524
- /**
525
- * Test the provided value for any urls and submit a request to obtain the service item id for the url
526
- *
527
- * @param v a string value to test for urls
528
- * @param authentication credentials for the requests
529
- * @returns an object with any pending requests and the urls that requests were made to
530
- */
531
- export function urlTest(v, authentication) {
532
- const urls = _getURLs(v);
533
- const requests = [];
534
- urls.forEach(url => {
535
- const options = {
536
- f: "json",
537
- authentication: authentication
538
- };
539
- requests.push(rest_request(url, options));
540
- });
541
- return {
542
- requests: requests,
543
- urls: urls
544
- };
545
- }
546
- //???
547
- export function _getURLs(v) {
548
- return regExTest(v, /=(http.*?FeatureServer.*?(?=&|$))/gi).map(_v => _v.replace("=", ""));
549
- }
550
- //#region Deploy Process ---------------------------------------------------------------------------------------//
551
- /**
552
- * Gets the current user and updates the dispatchers service
553
- *
554
- * @param newlyCreatedItem Item to be created; n.b.: this item is modified
555
- * @param destinationAuthentication The session used to create the new item(s)
556
- * @returns A promise that will resolve with \{ "success" === true || false \}
557
- */
558
- export function fineTuneCreatedWorkforceItem(newlyCreatedItem, destinationAuthentication, url, templateDictionary) {
559
- return new Promise((resolve, reject) => {
560
- destinationAuthentication.getUser().then(user => {
561
- // update url with slash if necessary
562
- url = _updateUrl(url);
563
- // Dispatchers...index 2 for workforce v2
564
- // for v1 we need tp fetch from dispatchers for v2 we use the items url
565
- const dispatchers = getProp(newlyCreatedItem, "data.dispatchers");
566
- // add current user as dispatcher
567
- _updateDispatchers(dispatchers && dispatchers.url ? dispatchers.url : `${url}2`, user.username || "", user.fullName || "", destinationAuthentication, templateDictionary.isPortal).then(results => {
568
- // for workforce v2 we storce the key details from the workforce service as workforceInfos
569
- // now we need to detemplatize it and update the workforce service
570
- let workforceInfos = getProp(newlyCreatedItem, "properties.workforceInfos");
571
- if (workforceInfos && url) {
572
- workforceInfos = replaceInTemplate(workforceInfos, templateDictionary);
573
- _getFields(url, [2, 3, 4], destinationAuthentication).then(fields => {
574
- // Assignment Types...index 3
575
- const assignmentTypeUrl = `${url}3`;
576
- const assignmentTypeInfos = workforceInfos.assignmentTypeInfos;
577
- const assignmentTypeFeatures = _getAddFeatures(assignmentTypeInfos, fields[assignmentTypeUrl]);
578
- const assignmentTypePromise = _applyEdits(assignmentTypeUrl, assignmentTypeFeatures, destinationAuthentication, true);
579
- // Assignment Integrations...index 4
580
- const assignmentIntegrationUrl = `${url}4`;
581
- const assignmentIntegrationInfos = workforceInfos.assignmentIntegrationInfos;
582
- const assignmentIntegrationFeatures = _getAddFeatures(assignmentIntegrationInfos, fields[assignmentIntegrationUrl]);
583
- const assignmentIntegrationPromise = _applyEdits(assignmentIntegrationUrl, assignmentIntegrationFeatures, destinationAuthentication, true);
584
- Promise.all([
585
- assignmentTypePromise,
586
- assignmentIntegrationPromise
587
- ]).then(resolve, reject);
588
- }, e => reject(fail(e)));
589
- }
590
- else {
591
- resolve({ success: results });
592
- }
593
- }, e => reject(fail(e)));
594
- }, e => reject(fail(e)));
595
- });
596
- }
597
- //???
598
- export function _getFields(url, ids, authentication) {
599
- return new Promise((resolve, reject) => {
600
- const options = {
601
- f: "json",
602
- fields: "*",
603
- authentication: authentication
604
- };
605
- url = _updateUrl(url);
606
- const promises = [];
607
- ids.forEach(id => {
608
- promises.push(rest_request(`${url}${id}`, options));
609
- });
610
- Promise.all(promises).then(results => {
611
- const finalResult = {};
612
- results.forEach(r => {
613
- finalResult[`${url}${r.id}`] = r.fields.map((f) => f.name);
614
- });
615
- resolve(finalResult);
616
- }, e => reject(fail(e)));
617
- });
618
- }
619
- //???
620
- export function _updateUrl(url) {
621
- url += url.endsWith("/") ? "" : "/";
622
- return url;
623
- }
624
- //???
625
- export function _getAddFeatures(updateInfos, fields) {
626
- const features = [];
627
- updateInfos.forEach((update) => {
628
- const f = {};
629
- Object.keys(update).forEach(k => {
630
- const fieldName = _getField(k, fields);
631
- f[fieldName] = update[k];
632
- });
633
- features.push({ attributes: f });
634
- });
635
- return features;
636
- }
637
- //???
638
- export function _getField(name, fields) {
639
- return fields.filter(f => f.toLowerCase() === name.toLowerCase())[0];
640
- }
641
- /**
642
- * Updates the dispatchers service to include the current user as a dispatcher
643
- *
644
- * @param dispatchers The dispatchers object from the workforce items data
645
- * @param name Current users name
646
- * @param fullName Current users full name
647
- * @param destinationAuthentication The session used to create the new item(s)
648
- * @returns A promise that will resolve with true || false
649
- * @private
650
- */
651
- export function _updateDispatchers(url, name, fullName, authentication, isPortal) {
652
- return new Promise((resolve, reject) => {
653
- if (url) {
654
- const fieldName = isPortal ? "userid" : "userId";
655
- queryFeatures({
656
- url,
657
- where: `${fieldName} = '${name}'`,
658
- authentication
659
- }).then((results) => {
660
- if (results && results.features) {
661
- if (results.features.length === 0) {
662
- const features = [
663
- {
664
- attributes: {
665
- name: fullName
666
- }
667
- }
668
- ];
669
- features[0].attributes[fieldName] = name;
670
- _applyEdits(url, features, authentication).then(resolve, reject);
671
- }
672
- else {
673
- resolve(true);
674
- }
675
- }
676
- else {
677
- resolve(false);
678
- }
679
- }, e => reject(fail(e)));
680
- }
681
- else {
682
- resolve(false);
683
- }
684
- });
685
- }
686
- //???
687
- export function _applyEdits(url, adds, authentication, useGlobalIds = false // only set when contains a globalid
688
- ) {
689
- return new Promise((resolve, reject) => {
690
- if (adds.length > 0) {
691
- applyEdits({
692
- url,
693
- adds,
694
- useGlobalIds,
695
- authentication
696
- }).then(addResults => {
697
- if (addResults && addResults.addResults) {
698
- resolve(true);
699
- }
700
- else {
701
- reject(fail({
702
- success: false,
703
- message: "Failed to add dispatch record."
704
- }));
705
- }
706
- }, e => reject(fail({
707
- success: false,
708
- message: "Failed to add dispatch record.",
709
- error: e
710
- })));
711
- }
712
- else {
713
- resolve(true);
714
- }
715
- });
716
- }
717
- //#endregion
1
+ /** @license
2
+ * Copyright 2020 Esri
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ /**
17
+ * Provides general helper functions.
18
+ *
19
+ * @module workforceHelpers
20
+ */
21
+ import { applyEdits, queryFeatures } from "@esri/arcgis-rest-feature-layer";
22
+ import { getIDs, getProp, fail, idTest, regExTest, setProp } from "./generalHelpers";
23
+ import { rest_request } from "./restHelpers";
24
+ import { templatizeTerm, replaceInTemplate } from "./templatization";
25
+ import { cacheLayerInfo } from "./featureServiceHelpers";
26
+ //#region workforce v1
27
+ /**
28
+ * Converts an workforce item to a template.
29
+ *
30
+ * @param itemTemplate template for the workforce project item
31
+ * @param authentication credentials for any requests
32
+ * @param templateDictionary Hash of key details used for variable replacement
33
+ * @returns templatized itemTemplate
34
+ */
35
+ export function convertWorkforceItemToTemplate(itemTemplate, authentication, templateDictionary) {
36
+ return new Promise((resolve, reject) => {
37
+ // This function is specific to workforce v1 project structure
38
+ // Key properties that contain item IDs for the workforce project type
39
+ const keyProperties = getKeyWorkforceProperties(1);
40
+ // The templates data to process
41
+ const data = itemTemplate.data;
42
+ if (data) {
43
+ // Extract dependencies
44
+ extractWorkforceDependencies(data, keyProperties, authentication).then(results => {
45
+ itemTemplate.dependencies = results.dependencies;
46
+ // templatize key properties
47
+ itemTemplate.data = templatizeWorkforce(data, keyProperties, results.urlHash, templateDictionary);
48
+ resolve(itemTemplate);
49
+ }, e => reject(fail(e)));
50
+ }
51
+ else {
52
+ resolve(itemTemplate);
53
+ }
54
+ });
55
+ }
56
+ /**
57
+ * Gets the ids of the dependencies of the workforce project.
58
+ *
59
+ * @param data itemTemplate data
60
+ * @param keyProperties workforce project properties that contain references to dependencies
61
+ * @param authentication credentials for any requests
62
+ * @returns List of dependencies ids
63
+ */
64
+ export function extractWorkforceDependencies(data, keyProperties, authentication) {
65
+ return new Promise((resolve, reject) => {
66
+ const deps = [];
67
+ // get the ids for the service dependencies
68
+ // "workerWebMapId" and "dispatcherWebMapId" are already IDs and don't have a serviceItemId
69
+ keyProperties.forEach(p => {
70
+ const serviceItemId = getProp(data, p + ".serviceItemId");
71
+ const v = getProp(data, p);
72
+ if (serviceItemId) {
73
+ if (deps.indexOf(serviceItemId) === -1) {
74
+ deps.push(serviceItemId);
75
+ }
76
+ }
77
+ else {
78
+ idTest(v, deps);
79
+ }
80
+ });
81
+ if (getProp(data, "assignmentIntegrations")) {
82
+ let requests = [];
83
+ let urls = [];
84
+ data.assignmentIntegrations.forEach((ai) => {
85
+ if (ai.assignmentTypes) {
86
+ const assignmentKeys = Object.keys(ai.assignmentTypes);
87
+ assignmentKeys.forEach(k => {
88
+ const urlTemplate = ai.assignmentTypes[k].urlTemplate;
89
+ idTest(urlTemplate, deps);
90
+ const serviceRequests = urlTest(urlTemplate, authentication);
91
+ if (Array.isArray(serviceRequests.requests) &&
92
+ serviceRequests.requests.length > 0) {
93
+ requests = requests.concat(serviceRequests.requests);
94
+ urls = urls.concat(serviceRequests.urls);
95
+ }
96
+ });
97
+ }
98
+ });
99
+ if (requests.length > 0) {
100
+ Promise.all(requests).then(results => {
101
+ const urlHash = {};
102
+ // Get the serviceItemId for the url
103
+ /* istanbul ignore else */
104
+ if (Array.isArray(results)) {
105
+ results.forEach((result, i) => {
106
+ /* istanbul ignore else */
107
+ if (result.serviceItemId) {
108
+ urlHash[urls[i]] = result.serviceItemId;
109
+ /* istanbul ignore else */
110
+ if (deps.indexOf(result.serviceItemId) === -1) {
111
+ deps.push(result.serviceItemId);
112
+ }
113
+ }
114
+ });
115
+ }
116
+ resolve({
117
+ dependencies: deps,
118
+ urlHash: urlHash
119
+ });
120
+ }, e => reject(fail(e)));
121
+ }
122
+ else {
123
+ resolve({
124
+ dependencies: deps,
125
+ urlHash: {}
126
+ });
127
+ }
128
+ }
129
+ else {
130
+ resolve({
131
+ dependencies: deps,
132
+ urlHash: {}
133
+ });
134
+ }
135
+ });
136
+ }
137
+ /**
138
+ * Templatizes key item properties.
139
+ *
140
+ * @param data itemTemplate data
141
+ * @param keyProperties workforce project properties that should be templatized
142
+ * @param urlHash a key value pair of url and itemId
143
+ * @param templateDictionary Hash of key details used for variable replacement
144
+ * @returns an updated data object to be stored in the template
145
+ */
146
+ export function templatizeWorkforce(data, keyProperties, urlHash, templateDictionary) {
147
+ keyProperties.forEach(p => {
148
+ /* istanbul ignore else */
149
+ if (getProp(data, p)) {
150
+ if (getProp(data[p], "serviceItemId")) {
151
+ // templatize properties with id and url
152
+ const id = data[p].serviceItemId;
153
+ let serviceItemIdSuffix = ".itemId";
154
+ /* istanbul ignore else */
155
+ if (getProp(data[p], "url")) {
156
+ const layerId = getLayerId(data[p].url);
157
+ cacheLayerInfo(layerId, id, data[p].url, templateDictionary);
158
+ data[p].url = templatizeTerm(id, id, getReplaceValue(layerId, ".url"));
159
+ serviceItemIdSuffix = getReplaceValue(layerId, serviceItemIdSuffix);
160
+ }
161
+ data[p].serviceItemId = templatizeTerm(id, id, serviceItemIdSuffix);
162
+ }
163
+ else {
164
+ // templatize simple id properties
165
+ data[p] = templatizeTerm(data[p], data[p], ".itemId");
166
+ }
167
+ }
168
+ });
169
+ data["folderId"] = "{{folderId}}";
170
+ // templatize app integrations
171
+ const integrations = data.assignmentIntegrations || [];
172
+ integrations.forEach(i => {
173
+ _templatizeUrlTemplate(i, urlHash);
174
+ /* istanbul ignore else */
175
+ if (i.assignmentTypes) {
176
+ const assignmentKeys = Object.keys(i.assignmentTypes);
177
+ assignmentKeys.forEach(k => {
178
+ _templatizeUrlTemplate(i.assignmentTypes[k], urlHash);
179
+ });
180
+ }
181
+ });
182
+ return data;
183
+ }
184
+ //#endregion
185
+ /**
186
+ * Evaluate key properties in the workforce service of additional items that are needed
187
+ *
188
+ * @param itemTemplate template for the workforce project item
189
+ * @param dependencies list of the items dependencies
190
+ * @returns an array of objects with dependency ids
191
+ */
192
+ export function getWorkforceDependencies(itemTemplate, dependencies) {
193
+ const properties = itemTemplate.item.properties || {};
194
+ const keyProperties = getKeyWorkforceProperties(2);
195
+ dependencies = keyProperties.reduce(function (acc, v) {
196
+ /* istanbul ignore else */
197
+ if (properties[v] && dependencies.indexOf(properties[v]) < 0) {
198
+ acc.push(properties[v]);
199
+ }
200
+ return acc;
201
+ }, dependencies);
202
+ // We also need the dependencies listed in the Assignment Integrations table
203
+ const infos = getProp(itemTemplate, "properties.workforceInfos.assignmentIntegrationInfos");
204
+ /* istanbul ignore else */
205
+ if (infos && infos.length > 0) {
206
+ infos.forEach((info) => {
207
+ const infoKeys = Object.keys(info);
208
+ /* istanbul ignore else */
209
+ if (infoKeys.indexOf("dependencies") > -1) {
210
+ info["dependencies"].forEach((d) => {
211
+ /* istanbul ignore else */
212
+ if (dependencies.indexOf(d) < 0) {
213
+ dependencies.push(d);
214
+ }
215
+ });
216
+ }
217
+ });
218
+ }
219
+ return dependencies.map(d => {
220
+ return { id: d, name: "" };
221
+ });
222
+ }
223
+ export function getWorkforceServiceInfo(properties, url, authentication) {
224
+ return new Promise((resolve, reject) => {
225
+ url = url.replace("/rest/admin/services", "/rest/services");
226
+ url = _updateUrl(url);
227
+ const requests = [
228
+ queryFeatures({
229
+ url: `${url}3`,
230
+ where: "1=1",
231
+ authentication
232
+ }),
233
+ queryFeatures({
234
+ url: `${url}4`,
235
+ where: "1=1",
236
+ authentication
237
+ })
238
+ ];
239
+ Promise.all(requests).then(responses => {
240
+ const [assignmentTypes, assignmentIntegrations] = responses;
241
+ properties.workforceInfos = {
242
+ assignmentTypeInfos: _getAssignmentTypeInfos(assignmentTypes)
243
+ };
244
+ _getAssignmentIntegrationInfos(assignmentIntegrations, authentication).then(results => {
245
+ properties.workforceInfos["assignmentIntegrationInfos"] = results;
246
+ _updateGlobalIdAndAssignmentType(properties.workforceInfos);
247
+ resolve(properties);
248
+ }, e => reject(fail(e)));
249
+ }, e => reject(fail(e)));
250
+ });
251
+ }
252
+ /**
253
+ * Wrap global id and assignmenttype values in curly braces
254
+ *
255
+ * Added for issue #734
256
+ *
257
+ * This function will update the provided workforceInfos object
258
+ *
259
+ * @param workforceInfos the object that stores the integration and type info with global ids
260
+ * @private
261
+ */
262
+ export function _updateGlobalIdAndAssignmentType(workforceInfos) {
263
+ const updateId = (i) => {
264
+ /* istanbul ignore else */
265
+ if (i["GlobalID"]) {
266
+ i["GlobalID"] = `{${i["GlobalID"]}}`;
267
+ }
268
+ /* istanbul ignore else */
269
+ if (i["assignmenttype"]) {
270
+ i["assignmenttype"] = `{${i["assignmenttype"]}}`;
271
+ }
272
+ return i;
273
+ };
274
+ const assignmentIntegrationInfos = getProp(workforceInfos, "assignmentIntegrationInfos");
275
+ /* istanbul ignore else */
276
+ if (assignmentIntegrationInfos && Array.isArray(assignmentIntegrationInfos)) {
277
+ setProp(workforceInfos, "assignmentIntegrationInfos", assignmentIntegrationInfos.map(updateId));
278
+ }
279
+ const assignmentTypeInfos = getProp(workforceInfos, "assignmentTypeInfos");
280
+ /* istanbul ignore else */
281
+ if (assignmentTypeInfos && Array.isArray(assignmentTypeInfos)) {
282
+ setProp(workforceInfos, "assignmentTypeInfos", assignmentTypeInfos.map(updateId));
283
+ }
284
+ }
285
+ //TODO: function doc
286
+ export function _getAssignmentTypeInfos(assignmentTypes) {
287
+ // Assignment Types
288
+ const assignmentTypeInfos = [];
289
+ const keyAssignmentTypeProps = [
290
+ "description",
291
+ assignmentTypes.globalIdFieldName
292
+ ];
293
+ assignmentTypes.features.forEach((f) => {
294
+ const info = {};
295
+ keyAssignmentTypeProps.forEach(p => {
296
+ info[p] = f.attributes[p];
297
+ });
298
+ assignmentTypeInfos.push(info);
299
+ });
300
+ return assignmentTypeInfos;
301
+ }
302
+ //TODO: function doc
303
+ export function _getAssignmentIntegrationInfos(assignmentIntegrations, authentication) {
304
+ return new Promise((resolve, reject) => {
305
+ let requests = [];
306
+ let urls = [];
307
+ const assignmentIntegrationInfos = [];
308
+ const keyAssignmentIntegrationsProps = [
309
+ "appid",
310
+ assignmentIntegrations.globalIdFieldName,
311
+ "prompt",
312
+ "urltemplate",
313
+ "assignmenttype"
314
+ ];
315
+ assignmentIntegrations.features.forEach((f) => {
316
+ const info = {};
317
+ keyAssignmentIntegrationsProps.forEach(p => {
318
+ info[p] = f.attributes[p];
319
+ /* istanbul ignore else */
320
+ if (p === "urltemplate") {
321
+ const urlTemplate = f.attributes[p];
322
+ const ids = getIDs(urlTemplate);
323
+ info["dependencies"] = ids;
324
+ const serviceRequests = urlTest(urlTemplate, authentication);
325
+ /* istanbul ignore else */
326
+ if (Array.isArray(serviceRequests.requests) &&
327
+ serviceRequests.requests.length > 0) {
328
+ requests = requests.concat(serviceRequests.requests);
329
+ urls = urls.concat(serviceRequests.urls);
330
+ }
331
+ }
332
+ });
333
+ assignmentIntegrationInfos.push(info);
334
+ });
335
+ getUrlDependencies(requests, urls).then(results => {
336
+ assignmentIntegrationInfos.forEach(ai => {
337
+ _templatizeUrlTemplate(ai, results.urlHash);
338
+ });
339
+ resolve(assignmentIntegrationInfos);
340
+ }, e => reject(fail(e)));
341
+ });
342
+ }
343
+ export function getUrlDependencies(requests, urls) {
344
+ return new Promise((resolve, reject) => {
345
+ const dependencies = [];
346
+ if (requests.length > 0) {
347
+ Promise.all(requests).then(results => {
348
+ const urlHash = {};
349
+ // Get the serviceItemId for the url
350
+ /* istanbul ignore else */
351
+ if (Array.isArray(results)) {
352
+ results.forEach((result, i) => {
353
+ /* istanbul ignore else */
354
+ if (result.serviceItemId) {
355
+ urlHash[urls[i]] = result.serviceItemId;
356
+ /* istanbul ignore else */
357
+ if (dependencies.indexOf(result.serviceItemId) === -1) {
358
+ dependencies.push(result.serviceItemId);
359
+ }
360
+ }
361
+ });
362
+ }
363
+ resolve({
364
+ dependencies,
365
+ urlHash
366
+ });
367
+ }, e => reject(fail(e)));
368
+ }
369
+ else {
370
+ resolve({
371
+ dependencies,
372
+ urlHash: {}
373
+ });
374
+ }
375
+ });
376
+ }
377
+ /**
378
+ * Templatizes values from a urlTemplate
379
+ *
380
+ * @param item the object that may contain a urlTemplate
381
+ * @param urlHash a key value pair of url and itemId
382
+ * @private
383
+ */
384
+ export function _templatizeUrlTemplate(item, urlHash) {
385
+ // v1 uses urlTemplate
386
+ // v2 uses urltemplate
387
+ const urlTemplateVar = getProp(item, "urlTemplate")
388
+ ? "urlTemplate"
389
+ : "urltemplate";
390
+ let urlTemplate = getProp(item, urlTemplateVar);
391
+ /* istanbul ignore else */
392
+ if (urlTemplate) {
393
+ const ids = getIDs(urlTemplate);
394
+ ids.forEach(id => {
395
+ urlTemplate = urlTemplate.replace(id, templatizeTerm(id, id, ".itemId"));
396
+ });
397
+ const urls = _getURLs(urlTemplate);
398
+ urls.forEach(url => {
399
+ const layerId = getLayerId(url);
400
+ const replaceValue = getReplaceValue(layerId, ".url");
401
+ const id = urlHash[url];
402
+ /* istanbul ignore else */
403
+ if (Array.isArray(item.dependencies) &&
404
+ item.dependencies.indexOf(id) < 0) {
405
+ item.dependencies.push(id);
406
+ }
407
+ urlTemplate = urlTemplate.replace(url, templatizeTerm(id, id, replaceValue));
408
+ });
409
+ setProp(item, urlTemplateVar, urlTemplate);
410
+ }
411
+ }
412
+ export function getLayerId(url) {
413
+ return url.indexOf("FeatureServer/") > -1
414
+ ? url.substr(url.lastIndexOf("/") + 1)
415
+ : undefined;
416
+ }
417
+ export function getReplaceValue(layerId, suffix) {
418
+ return isNaN(Number.parseInt(layerId, 10))
419
+ ? `${suffix}`
420
+ : `.layer${layerId}${suffix}`;
421
+ }
422
+ export function postProcessWorkforceTemplates(templates) {
423
+ const groupUpdates = {};
424
+ const _templates = templates.map(t => {
425
+ // templatize Workforce Project
426
+ t = _templatizeWorkforceProject(t, groupUpdates);
427
+ // templatize Workforce Dispatcher
428
+ t = _templatizeWorkforceDispatcherOrWorker(t, "Workforce Dispatcher");
429
+ // templatize Workforce Worker
430
+ t = _templatizeWorkforceDispatcherOrWorker(t, "Workforce Worker");
431
+ return t;
432
+ });
433
+ return _templates.map(t => {
434
+ if (groupUpdates[t.itemId]) {
435
+ t.dependencies = t.dependencies.concat(groupUpdates[t.itemId]);
436
+ }
437
+ return t;
438
+ });
439
+ }
440
+ //TODO: function doc
441
+ export function _templatizeWorkforceProject(t, groupUpdates) {
442
+ /* istanbul ignore else */
443
+ if (isWorkforceProject(t)) {
444
+ const properties = t.item.properties || {};
445
+ const keyProperties = getKeyWorkforceProperties(2);
446
+ const groupId = properties["workforceProjectGroupId"];
447
+ const shuffleIds = [];
448
+ Object.keys(properties).forEach((p) => {
449
+ /* istanbul ignore else */
450
+ if (keyProperties.indexOf(p) > -1) {
451
+ const id = properties[p];
452
+ /* istanbul ignore else */
453
+ if (id !== groupId) {
454
+ shuffleIds.push(id);
455
+ }
456
+ t.item.properties[p] = templatizeTerm(properties[p], properties[p], ".itemId");
457
+ }
458
+ });
459
+ // update the dependencies
460
+ t.dependencies = t.dependencies.filter((d) => d !== groupId && shuffleIds.indexOf(d) < 0);
461
+ // shuffle and cleanup
462
+ const workforceInfos = getProp(t, "properties.workforceInfos");
463
+ /* istanbul ignore else */
464
+ if (workforceInfos) {
465
+ Object.keys(workforceInfos).forEach(k => {
466
+ workforceInfos[k].forEach((wInfo) => {
467
+ /* istanbul ignore else */
468
+ if (wInfo.dependencies) {
469
+ wInfo.dependencies.forEach((id) => {
470
+ /* istanbul ignore else */
471
+ if (shuffleIds.indexOf(id) < 0) {
472
+ shuffleIds.push(id);
473
+ }
474
+ const depIndex = t.dependencies.indexOf(id);
475
+ /* istanbul ignore else */
476
+ if (depIndex > -1) {
477
+ t.dependencies.splice(depIndex, 1);
478
+ }
479
+ });
480
+ delete wInfo.dependencies;
481
+ }
482
+ });
483
+ });
484
+ }
485
+ // move the dependencies to the group
486
+ groupUpdates[groupId] = shuffleIds;
487
+ }
488
+ return t;
489
+ }
490
+ //TODO: function doc
491
+ export function _templatizeWorkforceDispatcherOrWorker(t, type) {
492
+ /* istanbul ignore else */
493
+ if ((t.item.typeKeywords || []).indexOf(type) > -1) {
494
+ const properties = t.item.properties || {};
495
+ const fsId = properties["workforceFeatureServiceId"];
496
+ /* istanbul ignore else */
497
+ if (fsId) {
498
+ t.item.properties["workforceFeatureServiceId"] = templatizeTerm(fsId, fsId, ".itemId");
499
+ }
500
+ }
501
+ return t;
502
+ }
503
+ // Helpers
504
+ export function isWorkforceProject(itemTemplate) {
505
+ return ((itemTemplate.item.typeKeywords || []).indexOf("Workforce Project") > -1);
506
+ }
507
+ export function getKeyWorkforceProperties(version) {
508
+ return version === 1
509
+ ? [
510
+ "groupId",
511
+ "workerWebMapId",
512
+ "dispatcherWebMapId",
513
+ "dispatchers",
514
+ "assignments",
515
+ "workers",
516
+ "tracks"
517
+ ]
518
+ : [
519
+ "workforceDispatcherMapId",
520
+ "workforceProjectGroupId",
521
+ "workforceWorkerMapId"
522
+ ];
523
+ }
524
+ /**
525
+ * Test the provided value for any urls and submit a request to obtain the service item id for the url
526
+ *
527
+ * @param v a string value to test for urls
528
+ * @param authentication credentials for the requests
529
+ * @returns an object with any pending requests and the urls that requests were made to
530
+ */
531
+ export function urlTest(v, authentication) {
532
+ const urls = _getURLs(v);
533
+ const requests = [];
534
+ urls.forEach(url => {
535
+ const options = {
536
+ f: "json",
537
+ authentication: authentication
538
+ };
539
+ requests.push(rest_request(url, options));
540
+ });
541
+ return {
542
+ requests: requests,
543
+ urls: urls
544
+ };
545
+ }
546
+ //TODO: function doc
547
+ export function _getURLs(v) {
548
+ return regExTest(v, /=(http.*?FeatureServer.*?(?=&|$))/gi).map(_v => _v.replace("=", ""));
549
+ }
550
+ //#region Deploy Process ---------------------------------------------------------------------------------------//
551
+ /**
552
+ * Gets the current user and updates the dispatchers service
553
+ *
554
+ * @param newlyCreatedItem Item to be created; n.b.: this item is modified
555
+ * @param destinationAuthentication The session used to create the new item(s)
556
+ * @returns A promise that will resolve with \{ "success" === true || false \}
557
+ */
558
+ export function fineTuneCreatedWorkforceItem(newlyCreatedItem, destinationAuthentication, url, templateDictionary) {
559
+ return new Promise((resolve, reject) => {
560
+ destinationAuthentication.getUser().then(user => {
561
+ // update url with slash if necessary
562
+ url = _updateUrl(url);
563
+ // Dispatchers...index 2 for workforce v2
564
+ // for v1 we need tp fetch from dispatchers for v2 we use the items url
565
+ const dispatchers = getProp(newlyCreatedItem, "data.dispatchers");
566
+ // add current user as dispatcher
567
+ _updateDispatchers(dispatchers && dispatchers.url ? dispatchers.url : `${url}2`, user.username || "", user.fullName || "", destinationAuthentication, templateDictionary.isPortal).then(results => {
568
+ // for workforce v2 we storce the key details from the workforce service as workforceInfos
569
+ // now we need to detemplatize it and update the workforce service
570
+ let workforceInfos = getProp(newlyCreatedItem, "properties.workforceInfos");
571
+ if (workforceInfos && url) {
572
+ workforceInfos = replaceInTemplate(workforceInfos, templateDictionary);
573
+ _getFields(url, [2, 3, 4], destinationAuthentication).then(fields => {
574
+ // Assignment Types...index 3
575
+ const assignmentTypeUrl = `${url}3`;
576
+ const assignmentTypeInfos = workforceInfos.assignmentTypeInfos;
577
+ const assignmentTypeFeatures = _getAddFeatures(assignmentTypeInfos, fields[assignmentTypeUrl]);
578
+ const assignmentTypePromise = _applyEdits(assignmentTypeUrl, assignmentTypeFeatures, destinationAuthentication, true);
579
+ // Assignment Integrations...index 4
580
+ const assignmentIntegrationUrl = `${url}4`;
581
+ const assignmentIntegrationInfos = workforceInfos.assignmentIntegrationInfos;
582
+ const assignmentIntegrationFeatures = _getAddFeatures(assignmentIntegrationInfos, fields[assignmentIntegrationUrl]);
583
+ const assignmentIntegrationPromise = _applyEdits(assignmentIntegrationUrl, assignmentIntegrationFeatures, destinationAuthentication, true);
584
+ Promise.all([
585
+ assignmentTypePromise,
586
+ assignmentIntegrationPromise
587
+ ]).then(resolve, reject);
588
+ }, e => reject(fail(e)));
589
+ }
590
+ else {
591
+ resolve({ success: results });
592
+ }
593
+ }, e => reject(fail(e)));
594
+ }, e => reject(fail(e)));
595
+ });
596
+ }
597
+ //TODO: function doc
598
+ export function _getFields(url, ids, authentication) {
599
+ return new Promise((resolve, reject) => {
600
+ const options = {
601
+ f: "json",
602
+ fields: "*",
603
+ authentication: authentication
604
+ };
605
+ url = _updateUrl(url);
606
+ const promises = [];
607
+ ids.forEach(id => {
608
+ promises.push(rest_request(`${url}${id}`, options));
609
+ });
610
+ Promise.all(promises).then(results => {
611
+ const finalResult = {};
612
+ results.forEach(r => {
613
+ finalResult[`${url}${r.id}`] = r.fields.map((f) => f.name);
614
+ });
615
+ resolve(finalResult);
616
+ }, e => reject(fail(e)));
617
+ });
618
+ }
619
+ //TODO: function doc
620
+ export function _updateUrl(url) {
621
+ url += url.endsWith("/") ? "" : "/";
622
+ return url;
623
+ }
624
+ //TODO: function doc
625
+ export function _getAddFeatures(updateInfos, fields) {
626
+ const features = [];
627
+ updateInfos.forEach((update) => {
628
+ const f = {};
629
+ Object.keys(update).forEach(k => {
630
+ const fieldName = _getField(k, fields);
631
+ f[fieldName] = update[k];
632
+ });
633
+ features.push({ attributes: f });
634
+ });
635
+ return features;
636
+ }
637
+ //TODO: function doc
638
+ export function _getField(name, fields) {
639
+ return fields.filter(f => f.toLowerCase() === name.toLowerCase())[0];
640
+ }
641
+ /**
642
+ * Updates the dispatchers service to include the current user as a dispatcher
643
+ *
644
+ * @param dispatchers The dispatchers object from the workforce items data
645
+ * @param name Current users name
646
+ * @param fullName Current users full name
647
+ * @param destinationAuthentication The session used to create the new item(s)
648
+ * @returns A promise that will resolve with true || false
649
+ * @private
650
+ */
651
+ export function _updateDispatchers(url, name, fullName, authentication, isPortal) {
652
+ return new Promise((resolve, reject) => {
653
+ if (url) {
654
+ const fieldName = isPortal ? "userid" : "userId";
655
+ queryFeatures({
656
+ url,
657
+ where: `${fieldName} = '${name}'`,
658
+ authentication
659
+ }).then((results) => {
660
+ if (results && results.features) {
661
+ if (results.features.length === 0) {
662
+ const features = [
663
+ {
664
+ attributes: {
665
+ name: fullName
666
+ }
667
+ }
668
+ ];
669
+ features[0].attributes[fieldName] = name;
670
+ _applyEdits(url, features, authentication).then(resolve, reject);
671
+ }
672
+ else {
673
+ resolve(true);
674
+ }
675
+ }
676
+ else {
677
+ resolve(false);
678
+ }
679
+ }, e => reject(fail(e)));
680
+ }
681
+ else {
682
+ resolve(false);
683
+ }
684
+ });
685
+ }
686
+ //TODO: function doc
687
+ export function _applyEdits(url, adds, authentication, useGlobalIds = false // only set when contains a globalid
688
+ ) {
689
+ return new Promise((resolve, reject) => {
690
+ if (adds.length > 0) {
691
+ applyEdits({
692
+ url,
693
+ adds,
694
+ useGlobalIds,
695
+ authentication
696
+ }).then(addResults => {
697
+ if (addResults && addResults.addResults) {
698
+ resolve(true);
699
+ }
700
+ else {
701
+ reject(fail({
702
+ success: false,
703
+ message: "Failed to add dispatch record."
704
+ }));
705
+ }
706
+ }, e => reject(fail({
707
+ success: false,
708
+ message: "Failed to add dispatch record.",
709
+ error: e
710
+ })));
711
+ }
712
+ else {
713
+ resolve(true);
714
+ }
715
+ });
716
+ }
717
+ //#endregion
718
718
  //# sourceMappingURL=workforceHelpers.js.map