angular-slickgrid 8.14.0 → 9.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 (419) hide show
  1. package/.gitbook.yaml +5 -0
  2. package/CHANGELOG.md +1691 -0
  3. package/CONTRIBUTING.md +17 -0
  4. package/README.md +13 -50
  5. package/angular.json +133 -0
  6. package/coverage/base.css +224 -0
  7. package/coverage/block-navigation.js +87 -0
  8. package/coverage/clover.xml +1620 -0
  9. package/coverage/coverage-final.json +9 -0
  10. package/coverage/favicon.png +0 -0
  11. package/coverage/index.html +176 -0
  12. package/coverage/library/components/angular-slickgrid.component.ts.html +5074 -0
  13. package/coverage/library/components/index.html +116 -0
  14. package/coverage/library/constants.ts.html +397 -0
  15. package/coverage/library/extensions/index.html +116 -0
  16. package/coverage/library/extensions/slickRowDetailView.ts.html +1261 -0
  17. package/coverage/library/index.html +116 -0
  18. package/coverage/library/modules/angular-slickgrid.module.ts.html +166 -0
  19. package/coverage/library/modules/index.html +116 -0
  20. package/coverage/library/services/angularUtil.service.ts.html +445 -0
  21. package/coverage/library/services/container.service.ts.html +163 -0
  22. package/coverage/library/services/index.html +161 -0
  23. package/coverage/library/services/translater.service.ts.html +199 -0
  24. package/coverage/library/services/utilities.ts.html +142 -0
  25. package/coverage/prettify.css +1 -0
  26. package/coverage/prettify.js +2 -0
  27. package/coverage/sort-arrow-sprite.png +0 -0
  28. package/coverage/sorter.js +196 -0
  29. package/dist/LICENSE +21 -0
  30. package/dist/README.md +142 -0
  31. package/{fesm2022 → dist/fesm2022}/angular-slickgrid.mjs +175 -198
  32. package/dist/fesm2022/angular-slickgrid.mjs.map +1 -0
  33. package/{i18n → dist/i18n}/en.json +2 -1
  34. package/{i18n → dist/i18n}/fr.json +2 -1
  35. package/{app/modules/angular-slickgrid → dist/library}/components/angular-slickgrid.component.d.ts +9 -9
  36. package/{app/modules/angular-slickgrid → dist/library}/extensions/slickRowDetailView.d.ts +4 -4
  37. package/{app/modules/angular-slickgrid → dist/library}/models/angularGridInstance.interface.d.ts +0 -2
  38. package/dist/library/models/index.d.ts +5 -0
  39. package/{app/modules/angular-slickgrid → dist/library}/models/rowDetailView.interface.d.ts +1 -1
  40. package/{app/modules/angular-slickgrid → dist/library}/modules/angular-slickgrid.module.d.ts +1 -1
  41. package/dist/public_api.d.ts +1 -0
  42. package/docs/README.md +5 -0
  43. package/docs/TOC.md +105 -0
  44. package/docs/backend-services/Custom-Backend-Service.md +50 -0
  45. package/docs/backend-services/GraphQL.md +276 -0
  46. package/docs/backend-services/OData.md +245 -0
  47. package/docs/backend-services/graphql/GraphQL-Filtering.md +156 -0
  48. package/docs/backend-services/graphql/GraphQL-JSON-Result.md +85 -0
  49. package/docs/backend-services/graphql/GraphQL-Pagination.md +77 -0
  50. package/docs/backend-services/graphql/GraphQL-Sorting.md +78 -0
  51. package/docs/column-functionalities/cell-menu.md +212 -0
  52. package/docs/column-functionalities/editors/autocomplete-editor.md +466 -0
  53. package/docs/column-functionalities/editors/date-editor-flatpickr.md +71 -0
  54. package/docs/column-functionalities/editors/date-editor-vanilla-calendar.md +91 -0
  55. package/docs/column-functionalities/editors/longtext-editor-textarea.md +80 -0
  56. package/docs/column-functionalities/editors/select-dropdown-editor.md +227 -0
  57. package/docs/column-functionalities/editors.md +604 -0
  58. package/docs/column-functionalities/filters/autocomplete-filter.md +183 -0
  59. package/docs/column-functionalities/filters/compound-filters.md +234 -0
  60. package/docs/column-functionalities/filters/custom-filter.md +117 -0
  61. package/docs/column-functionalities/filters/filter-intro.md +81 -0
  62. package/docs/column-functionalities/filters/input-filter.md +260 -0
  63. package/docs/column-functionalities/filters/range-filters.md +188 -0
  64. package/docs/column-functionalities/filters/select-filter.md +695 -0
  65. package/docs/column-functionalities/filters/single-search-filter.md +77 -0
  66. package/docs/column-functionalities/filters/styling-filled-filters.md +45 -0
  67. package/docs/column-functionalities/formatters.md +325 -0
  68. package/docs/column-functionalities/sorting.md +200 -0
  69. package/docs/developer-guides/csp-compliance.md +64 -0
  70. package/docs/events/Available-Events.md +223 -0
  71. package/docs/events/Grid-&-DataView-Events.md +211 -0
  72. package/docs/getting-started/quick-start.md +230 -0
  73. package/docs/getting-started/troubleshooting.md +80 -0
  74. package/docs/grid-functionalities/Column-Picker.md +22 -0
  75. package/docs/grid-functionalities/Composite-Editor-Modal.md +627 -0
  76. package/docs/grid-functionalities/Context-Menu.md +226 -0
  77. package/docs/grid-functionalities/Custom-Footer.md +80 -0
  78. package/docs/grid-functionalities/Custom-Tooltip-(plugin).md +258 -0
  79. package/docs/grid-functionalities/Export-to-Excel.md +457 -0
  80. package/docs/grid-functionalities/Export-to-Text-File.md +165 -0
  81. package/docs/grid-functionalities/FAQ.md +53 -0
  82. package/docs/grid-functionalities/Global-Options.md +29 -0
  83. package/docs/grid-functionalities/Grid-Auto-Resize.md +218 -0
  84. package/docs/grid-functionalities/Grid-Menu.md +134 -0
  85. package/docs/grid-functionalities/Grid-State-&-Preset.md +245 -0
  86. package/docs/grid-functionalities/Header-Menu-&-Header-Buttons.md +125 -0
  87. package/docs/grid-functionalities/Resize-by-Cell-Content.md +138 -0
  88. package/docs/grid-functionalities/Row-Selection.md +247 -0
  89. package/docs/grid-functionalities/Row-based-edit.md +71 -0
  90. package/docs/grid-functionalities/add-update-highlight.md +258 -0
  91. package/docs/grid-functionalities/column-row-spanning.md +74 -0
  92. package/docs/grid-functionalities/dynamic-item-metadata.md +124 -0
  93. package/docs/grid-functionalities/excel-copy-buffer.md +145 -0
  94. package/docs/grid-functionalities/frozen-columns-rows.md +164 -0
  95. package/docs/grid-functionalities/grouping-and-aggregators.md +269 -0
  96. package/docs/grid-functionalities/header-footer-slots.md +22 -0
  97. package/docs/grid-functionalities/infinite-scroll.md +150 -0
  98. package/docs/grid-functionalities/providing-grid-data.md +61 -0
  99. package/docs/grid-functionalities/row-detail.md +530 -0
  100. package/docs/grid-functionalities/tree-data-grid.md +391 -0
  101. package/docs/localization/Localization---Component-Sample.md +87 -0
  102. package/docs/localization/Localization-with-Custom-Locales.md +66 -0
  103. package/docs/localization/Localization-with-ngx-translate.md +148 -0
  104. package/docs/migrations/migration-to-2.x.md +304 -0
  105. package/docs/migrations/migration-to-3.x.md +295 -0
  106. package/docs/migrations/migration-to-4.x.md +83 -0
  107. package/docs/migrations/migration-to-5.x.md +160 -0
  108. package/docs/migrations/migration-to-6.x.md +128 -0
  109. package/docs/migrations/migration-to-7.x.md +294 -0
  110. package/docs/migrations/migration-to-8.x.md +316 -0
  111. package/docs/migrations/migration-to-9.x.md +219 -0
  112. package/docs/slick-grid-dataview-objects/slickgrid-dataview-objects.md +79 -0
  113. package/docs/styling/dark-mode.md +100 -0
  114. package/docs/styling/styling.md +250 -0
  115. package/docs/testing/testing-patterns.md +73 -0
  116. package/eslint.config.mjs +60 -0
  117. package/ng-package.json +10 -0
  118. package/package.json +24 -48
  119. package/src/assets/angular-logo.png +0 -0
  120. package/src/assets/angular-logo2.png +0 -0
  121. package/src/assets/data/collection_100_numbers.json +12 -0
  122. package/src/assets/data/collection_500_numbers.json +52 -0
  123. package/src/assets/data/countries.json +245 -0
  124. package/src/assets/data/country_names.json +245 -0
  125. package/src/assets/data/customers_100.json +102 -0
  126. package/src/assets/data/users.csv +5 -0
  127. package/src/assets/i18n/en.json +102 -0
  128. package/src/assets/i18n/fr.json +103 -0
  129. package/src/demos/app-routing.module.ts +108 -0
  130. package/src/demos/app.component.html +187 -0
  131. package/src/demos/app.component.scss +79 -0
  132. package/src/demos/app.component.ts +11 -0
  133. package/src/demos/app.module.ts +196 -0
  134. package/src/demos/environments/environment.dev.ts +3 -0
  135. package/src/demos/environments/environment.prod.ts +3 -0
  136. package/src/demos/environments/environment.ts +8 -0
  137. package/src/demos/examples/custom-angularComponentEditor.ts +187 -0
  138. package/src/demos/examples/custom-angularComponentFilter.ts +123 -0
  139. package/src/demos/examples/custom-buttonFormatter.component.ts +13 -0
  140. package/src/demos/examples/custom-inputEditor.ts +132 -0
  141. package/src/demos/examples/custom-inputFilter.ts +134 -0
  142. package/src/demos/examples/custom-titleFormatter.component.ts +9 -0
  143. package/src/demos/examples/data/collection_100_numbers.json +12 -0
  144. package/src/demos/examples/data/collection_500_numbers.json +52 -0
  145. package/src/demos/examples/data/countries.json +245 -0
  146. package/src/demos/examples/data/country_names.json +245 -0
  147. package/src/demos/examples/data/customers_100.json +102 -0
  148. package/src/demos/examples/data/users.csv +5 -0
  149. package/src/demos/examples/editor-ng-select.component.ts +38 -0
  150. package/src/demos/examples/example01.component.html +48 -0
  151. package/src/demos/examples/example01.component.ts +109 -0
  152. package/src/demos/examples/example02.component.html +45 -0
  153. package/src/demos/examples/example02.component.ts +218 -0
  154. package/src/demos/examples/example03.component.html +118 -0
  155. package/src/demos/examples/example03.component.ts +694 -0
  156. package/src/demos/examples/example04.component.html +87 -0
  157. package/src/demos/examples/example04.component.ts +326 -0
  158. package/src/demos/examples/example05.component.html +151 -0
  159. package/src/demos/examples/example05.component.ts +474 -0
  160. package/src/demos/examples/example06.component.html +163 -0
  161. package/src/demos/examples/example06.component.ts +446 -0
  162. package/src/demos/examples/example07.component.html +56 -0
  163. package/src/demos/examples/example07.component.scss +10 -0
  164. package/src/demos/examples/example07.component.ts +216 -0
  165. package/src/demos/examples/example08.component.html +51 -0
  166. package/src/demos/examples/example08.component.scss +23 -0
  167. package/src/demos/examples/example08.component.ts +195 -0
  168. package/src/demos/examples/example09.component.html +55 -0
  169. package/src/demos/examples/example09.component.scss +22 -0
  170. package/src/demos/examples/example09.component.ts +302 -0
  171. package/src/demos/examples/example10.component.html +103 -0
  172. package/src/demos/examples/example10.component.ts +309 -0
  173. package/src/demos/examples/example11.component.html +91 -0
  174. package/src/demos/examples/example11.component.ts +276 -0
  175. package/src/demos/examples/example12.component.html +98 -0
  176. package/src/demos/examples/example12.component.ts +317 -0
  177. package/src/demos/examples/example13.component.html +96 -0
  178. package/src/demos/examples/example13.component.ts +370 -0
  179. package/src/demos/examples/example14.component.html +50 -0
  180. package/src/demos/examples/example14.component.scss +11 -0
  181. package/src/demos/examples/example14.component.ts +156 -0
  182. package/src/demos/examples/example15.component.html +56 -0
  183. package/src/demos/examples/example15.component.ts +304 -0
  184. package/src/demos/examples/example16.component.html +77 -0
  185. package/src/demos/examples/example16.component.ts +277 -0
  186. package/src/demos/examples/example17.component.html +50 -0
  187. package/src/demos/examples/example17.component.ts +109 -0
  188. package/src/demos/examples/example18.component.html +132 -0
  189. package/src/demos/examples/example18.component.ts +445 -0
  190. package/src/demos/examples/example19-rowdetail.component.html +40 -0
  191. package/src/demos/examples/example19-rowdetail.component.ts +54 -0
  192. package/src/demos/examples/example19.component.html +79 -0
  193. package/src/demos/examples/example19.component.ts +316 -0
  194. package/src/demos/examples/example20.component.html +76 -0
  195. package/src/demos/examples/example20.component.scss +11 -0
  196. package/src/demos/examples/example20.component.ts +341 -0
  197. package/src/demos/examples/example21.component.html +86 -0
  198. package/src/demos/examples/example21.component.scss +16 -0
  199. package/src/demos/examples/example21.component.ts +140 -0
  200. package/src/demos/examples/example22.component.html +41 -0
  201. package/src/demos/examples/example22.component.ts +117 -0
  202. package/src/demos/examples/example23.component.html +111 -0
  203. package/src/demos/examples/example23.component.ts +323 -0
  204. package/src/demos/examples/example24.component.html +120 -0
  205. package/src/demos/examples/example24.component.scss +62 -0
  206. package/src/demos/examples/example24.component.ts +641 -0
  207. package/src/demos/examples/example25.component.html +60 -0
  208. package/src/demos/examples/example25.component.scss +8 -0
  209. package/src/demos/examples/example25.component.ts +255 -0
  210. package/src/demos/examples/example26.component.html +98 -0
  211. package/src/demos/examples/example26.component.scss +42 -0
  212. package/src/demos/examples/example26.component.ts +383 -0
  213. package/src/demos/examples/example27.component.html +138 -0
  214. package/src/demos/examples/example27.component.scss +10 -0
  215. package/src/demos/examples/example27.component.ts +369 -0
  216. package/src/demos/examples/example28.component.html +143 -0
  217. package/src/demos/examples/example28.component.scss +54 -0
  218. package/src/demos/examples/example28.component.ts +453 -0
  219. package/src/demos/examples/example29.component.html +30 -0
  220. package/src/demos/examples/example29.component.ts +70 -0
  221. package/src/demos/examples/example30.component.html +116 -0
  222. package/src/demos/examples/example30.component.scss +20 -0
  223. package/src/demos/examples/example30.component.ts +1070 -0
  224. package/src/demos/examples/example32.component.html +77 -0
  225. package/src/demos/examples/example32.component.scss +8 -0
  226. package/src/demos/examples/example32.component.ts +905 -0
  227. package/src/demos/examples/example33.component.html +50 -0
  228. package/src/demos/examples/example33.component.scss +46 -0
  229. package/src/demos/examples/example33.component.ts +571 -0
  230. package/src/demos/examples/example34.component.html +82 -0
  231. package/src/demos/examples/example34.component.scss +77 -0
  232. package/src/demos/examples/example34.component.ts +434 -0
  233. package/src/demos/examples/example35.component.html +77 -0
  234. package/src/demos/examples/example35.component.scss +18 -0
  235. package/src/demos/examples/example35.component.ts +264 -0
  236. package/src/demos/examples/example36.component.html +56 -0
  237. package/src/demos/examples/example36.component.scss +26 -0
  238. package/src/demos/examples/example36.component.ts +504 -0
  239. package/src/demos/examples/example37.component.html +30 -0
  240. package/src/demos/examples/example37.component.ts +123 -0
  241. package/src/demos/examples/example38.component.html +104 -0
  242. package/src/demos/examples/example38.component.scss +8 -0
  243. package/src/demos/examples/example38.component.ts +420 -0
  244. package/src/demos/examples/example39.component.html +112 -0
  245. package/src/demos/examples/example39.component.scss +8 -0
  246. package/src/demos/examples/example39.component.ts +371 -0
  247. package/src/demos/examples/example40.component.html +76 -0
  248. package/src/demos/examples/example40.component.ts +226 -0
  249. package/src/demos/examples/example41.component.html +50 -0
  250. package/src/demos/examples/example41.component.scss +42 -0
  251. package/src/demos/examples/example41.component.ts +229 -0
  252. package/src/demos/examples/example42.component.html +47 -0
  253. package/src/demos/examples/example42.component.ts +203 -0
  254. package/src/demos/examples/example43.component.html +94 -0
  255. package/src/demos/examples/example43.component.scss +30 -0
  256. package/src/demos/examples/example43.component.ts +449 -0
  257. package/src/demos/examples/example44.component.html +78 -0
  258. package/src/demos/examples/example44.component.scss +50 -0
  259. package/src/demos/examples/example44.component.ts +375 -0
  260. package/src/demos/examples/example45-detail.component.html +15 -0
  261. package/src/demos/examples/example45-detail.component.ts +97 -0
  262. package/src/demos/examples/example45.component.html +110 -0
  263. package/src/demos/examples/example45.component.scss +50 -0
  264. package/src/demos/examples/example45.component.ts +243 -0
  265. package/src/demos/examples/filter-ng-select.component.ts +33 -0
  266. package/src/demos/examples/grid-custom-pager.component.html +60 -0
  267. package/src/demos/examples/grid-custom-pager.component.scss +57 -0
  268. package/src/demos/examples/grid-custom-pager.component.ts +107 -0
  269. package/src/demos/examples/grid-remote.component.html +44 -0
  270. package/src/demos/examples/grid-remote.component.ts +164 -0
  271. package/src/demos/examples/home.component.html +39 -0
  272. package/src/demos/examples/home.component.ts +10 -0
  273. package/src/demos/examples/jsonp.ts +89 -0
  274. package/src/demos/examples/rowdetail-preload.component.ts +10 -0
  275. package/src/demos/examples/swt-common-grid-pagination.component.ts +160 -0
  276. package/src/demos/examples/swt-common-grid-test.component.html +37 -0
  277. package/src/demos/examples/swt-common-grid-test.component.ts +214 -0
  278. package/src/demos/examples/swt-common-grid.component.ts +436 -0
  279. package/src/demos/examples/swt-logger.service.ts +173 -0
  280. package/src/demos/examples/utilities.ts +9 -0
  281. package/src/favicon.ico +0 -0
  282. package/src/index.html +17 -0
  283. package/src/library/components/__tests__/angular-slickgrid.component.spec.ts +2638 -0
  284. package/src/library/components/angular-slickgrid.component.html +5 -0
  285. package/src/library/components/angular-slickgrid.component.ts +1662 -0
  286. package/src/library/constants.ts +105 -0
  287. package/src/library/extensions/__tests__/slickRowDetailView.spec.ts +751 -0
  288. package/src/library/extensions/index.ts +1 -0
  289. package/src/library/extensions/slickRowDetailView.ts +395 -0
  290. package/src/library/global-grid-options.ts +273 -0
  291. package/src/library/index.ts +11 -0
  292. package/src/library/models/angularComponentOutput.interface.ts +6 -0
  293. package/src/library/models/angularGridInstance.interface.ts +76 -0
  294. package/src/library/models/externalTestingDependencies.interface.ts +37 -0
  295. package/src/library/models/gridOption.interface.ts +15 -0
  296. package/src/library/models/index.ts +5 -0
  297. package/src/library/models/rowDetailView.interface.ts +16 -0
  298. package/src/library/modules/angular-slickgrid.module.spec.ts +25 -0
  299. package/src/library/modules/angular-slickgrid.module.ts +27 -0
  300. package/src/library/services/__tests__/angularUtilService.spec.ts +156 -0
  301. package/src/library/services/__tests__/container.service.spec.ts +25 -0
  302. package/src/library/services/__tests__/translater.service.spec.ts +43 -0
  303. package/src/library/services/__tests__/utilities.spec.ts +22 -0
  304. package/src/library/services/angularUtil.service.ts +120 -0
  305. package/src/library/services/container.service.ts +26 -0
  306. package/src/library/services/index.ts +4 -0
  307. package/src/library/services/translater.service.ts +38 -0
  308. package/src/library/services/utilities.ts +19 -0
  309. package/src/library/slickgrid-config.ts +10 -0
  310. package/src/main.ts +13 -0
  311. package/src/public_api.ts +1 -0
  312. package/src/styles.scss +178 -0
  313. package/test/cypress/e2e/example01.cy.ts +367 -0
  314. package/test/cypress/e2e/example02.cy.ts +60 -0
  315. package/test/cypress/e2e/example03.cy.ts +268 -0
  316. package/test/cypress/e2e/example04.cy.ts +254 -0
  317. package/test/cypress/e2e/example05.cy.ts +804 -0
  318. package/test/cypress/e2e/example06.cy.ts +890 -0
  319. package/test/cypress/e2e/example07.cy.ts +384 -0
  320. package/test/cypress/e2e/example08.cy.ts +190 -0
  321. package/test/cypress/e2e/example09.cy.ts +392 -0
  322. package/test/cypress/e2e/example10.cy.ts +650 -0
  323. package/test/cypress/e2e/example11.cy.ts +86 -0
  324. package/test/cypress/e2e/example12.cy.ts +269 -0
  325. package/test/cypress/e2e/example13.cy.ts +246 -0
  326. package/test/cypress/e2e/example14.cy.ts +122 -0
  327. package/test/cypress/e2e/example15.cy.ts +598 -0
  328. package/test/cypress/e2e/example16.cy.ts +427 -0
  329. package/test/cypress/e2e/example17.cy.ts +83 -0
  330. package/test/cypress/e2e/example18.cy.ts +431 -0
  331. package/test/cypress/e2e/example19.cy.ts +263 -0
  332. package/test/cypress/e2e/example20.cy.ts +264 -0
  333. package/test/cypress/e2e/example21.cy.ts +77 -0
  334. package/test/cypress/e2e/example22.cy.ts +94 -0
  335. package/test/cypress/e2e/example23.cy.ts +259 -0
  336. package/test/cypress/e2e/example24.cy.ts +707 -0
  337. package/test/cypress/e2e/example25.cy.ts +193 -0
  338. package/test/cypress/e2e/example26.cy.ts +111 -0
  339. package/test/cypress/e2e/example27.cy.ts +261 -0
  340. package/test/cypress/e2e/example28.cy.ts +740 -0
  341. package/test/cypress/e2e/example29.cy.ts +30 -0
  342. package/test/cypress/e2e/example30.cy.ts +757 -0
  343. package/test/cypress/e2e/example31.cy.ts +69 -0
  344. package/test/cypress/e2e/example32.cy.ts +272 -0
  345. package/test/cypress/e2e/example33.cy.ts +278 -0
  346. package/test/cypress/e2e/example34.cy.ts +84 -0
  347. package/test/cypress/e2e/example35.cy.ts +178 -0
  348. package/test/cypress/e2e/example36.cy.ts +219 -0
  349. package/test/cypress/e2e/example37.cy.ts +52 -0
  350. package/test/cypress/e2e/example38.cy.ts +160 -0
  351. package/test/cypress/e2e/example39.cy.ts +150 -0
  352. package/test/cypress/e2e/example40.cy.ts +126 -0
  353. package/test/cypress/e2e/example41.cy.ts +90 -0
  354. package/test/cypress/e2e/example42.cy.ts +82 -0
  355. package/test/cypress/e2e/example43.cy.ts +482 -0
  356. package/test/cypress/e2e/example44.cy.ts +458 -0
  357. package/test/cypress/e2e/example45.cy.ts +455 -0
  358. package/test/cypress/e2e/home.cy.ts +7 -0
  359. package/test/cypress/fixtures/example.json +5 -0
  360. package/test/cypress/plugins/index.ts +17 -0
  361. package/test/cypress/plugins/utilities.ts +28 -0
  362. package/test/cypress/support/commands.ts +88 -0
  363. package/test/cypress/support/common.ts +47 -0
  364. package/test/cypress/support/drag.ts +101 -0
  365. package/test/cypress/support/index.ts +20 -0
  366. package/test/cypress/tsconfig.json +9 -0
  367. package/test/cypress.config.ts +34 -0
  368. package/test/mockSlickEvent.ts +77 -0
  369. package/test/rxjsResourceStub.ts +69 -0
  370. package/test/test-setup.ts +6 -0
  371. package/test/translateServiceStub.ts +230 -0
  372. package/test/translaterServiceStub.ts +239 -0
  373. package/test/tsconfig.json +17 -0
  374. package/test/vitest-global-mocks.ts +41 -0
  375. package/test/vitest-global-setup.ts +3 -0
  376. package/test/vitest-pretest.ts +5 -0
  377. package/tsconfig.app.json +14 -0
  378. package/tsconfig.json +31 -0
  379. package/tsconfig.spec.json +11 -0
  380. package/types/sortablejs.d.ts +4 -0
  381. package/vite.config.mts +51 -0
  382. package/app/modules/angular-slickgrid/models/index.d.ts +0 -5
  383. package/esm2022/angular-slickgrid.mjs +0 -5
  384. package/esm2022/app/modules/angular-slickgrid/components/angular-slickgrid.component.mjs +0 -1407
  385. package/esm2022/app/modules/angular-slickgrid/constants.mjs +0 -96
  386. package/esm2022/app/modules/angular-slickgrid/extensions/index.mjs +0 -2
  387. package/esm2022/app/modules/angular-slickgrid/extensions/slickRowDetailView.mjs +0 -301
  388. package/esm2022/app/modules/angular-slickgrid/global-grid-options.mjs +0 -263
  389. package/esm2022/app/modules/angular-slickgrid/index.mjs +0 -8
  390. package/esm2022/app/modules/angular-slickgrid/models/angularComponentOutput.interface.mjs +0 -2
  391. package/esm2022/app/modules/angular-slickgrid/models/angularGridInstance.interface.mjs +0 -2
  392. package/esm2022/app/modules/angular-slickgrid/models/externalTestingDependencies.interface.mjs +0 -2
  393. package/esm2022/app/modules/angular-slickgrid/models/gridOption.interface.mjs +0 -2
  394. package/esm2022/app/modules/angular-slickgrid/models/index.mjs +0 -6
  395. package/esm2022/app/modules/angular-slickgrid/models/rowDetailView.interface.mjs +0 -2
  396. package/esm2022/app/modules/angular-slickgrid/modules/angular-slickgrid.module.mjs +0 -32
  397. package/esm2022/app/modules/angular-slickgrid/services/angularUtil.service.mjs +0 -88
  398. package/esm2022/app/modules/angular-slickgrid/services/container.service.mjs +0 -27
  399. package/esm2022/app/modules/angular-slickgrid/services/index.mjs +0 -5
  400. package/esm2022/app/modules/angular-slickgrid/services/translater.service.mjs +0 -45
  401. package/esm2022/app/modules/angular-slickgrid/services/utilities.mjs +0 -19
  402. package/esm2022/app/modules/angular-slickgrid/slickgrid-config.mjs +0 -8
  403. package/esm2022/public_api.mjs +0 -2
  404. package/fesm2022/angular-slickgrid.mjs.map +0 -1
  405. package/public_api.d.ts +0 -1
  406. /package/{index.d.ts → dist/index.d.ts} +0 -0
  407. /package/{app/modules/angular-slickgrid → dist/library}/constants.d.ts +0 -0
  408. /package/{app/modules/angular-slickgrid → dist/library}/extensions/index.d.ts +0 -0
  409. /package/{app/modules/angular-slickgrid → dist/library}/global-grid-options.d.ts +0 -0
  410. /package/{app/modules/angular-slickgrid → dist/library}/index.d.ts +0 -0
  411. /package/{app/modules/angular-slickgrid → dist/library}/models/angularComponentOutput.interface.d.ts +0 -0
  412. /package/{app/modules/angular-slickgrid → dist/library}/models/externalTestingDependencies.interface.d.ts +0 -0
  413. /package/{app/modules/angular-slickgrid → dist/library}/models/gridOption.interface.d.ts +0 -0
  414. /package/{app/modules/angular-slickgrid → dist/library}/services/angularUtil.service.d.ts +0 -0
  415. /package/{app/modules/angular-slickgrid → dist/library}/services/container.service.d.ts +0 -0
  416. /package/{app/modules/angular-slickgrid → dist/library}/services/index.d.ts +0 -0
  417. /package/{app/modules/angular-slickgrid → dist/library}/services/translater.service.d.ts +0 -0
  418. /package/{app/modules/angular-slickgrid → dist/library}/services/utilities.d.ts +0 -0
  419. /package/{app/modules/angular-slickgrid → dist/library}/slickgrid-config.d.ts +0 -0
@@ -0,0 +1,890 @@
1
+ import { addDay, format } from '@formkit/tempo';
2
+
3
+ import { removeWhitespaces } from '../plugins/utilities';
4
+
5
+ const currentYear = new Date().getFullYear();
6
+ const presetLowestDay = `${currentYear}-01-01`;
7
+ const presetHighestDay = `${currentYear}-02-15`;
8
+ function removeSpaces(textS) {
9
+ return `${textS}`.replace(/\s+/g, '');
10
+ }
11
+
12
+ describe('Example 6 - GraphQL Grid', { retries: 0 }, () => {
13
+ it('should display Example title', () => {
14
+ cy.visit(`${Cypress.config('baseUrl')}/example06`);
15
+ cy.get('h2').should('contain', 'Example 6: Grid connected to Backend Server with GraphQL');
16
+ });
17
+
18
+ it('should have a grid of size 900 by 200px', () => {
19
+ cy.get('#slickGridContainer-grid6').should('have.css', 'width', '900px');
20
+
21
+ cy.get('#slickGridContainer-grid6 > .slickgrid-container').should(($el) => expect(parseInt(`${$el.height()}`, 10)).to.eq(200));
22
+ });
23
+
24
+ it('should have English Text inside some of the Filters', () => {
25
+ cy.get('.search-filter.filter-gender .ms-choice > span').contains('Male');
26
+ });
27
+
28
+ it('should have GraphQL query with defined Grid Presets', () => {
29
+ cy.get('.search-filter.filter-name select').should('not.have.value');
30
+
31
+ cy.get('.search-filter.filter-name')
32
+ .find('input')
33
+ .invoke('val')
34
+ .then((text) => expect(text).to.eq('Joh*oe'));
35
+
36
+ cy.get('.search-filter.filter-gender .ms-choice > span').contains('Male');
37
+
38
+ cy.get('.search-filter.filter-company .ms-choice > span').contains('Company XYZ');
39
+
40
+ cy.get('.search-filter.filter-finish')
41
+ .find('input')
42
+ .invoke('val')
43
+ .then((text) => expect(text).to.eq(`${presetLowestDay} — ${presetHighestDay}`));
44
+
45
+ cy.get('[data-test=alert-graphql-query]').should('exist');
46
+ cy.get('[data-test=alert-graphql-query]').should('contain', 'GraphQL Query');
47
+
48
+ // wait for the query to finish
49
+ cy.get('[data-test=status]').should('contain', 'finished');
50
+
51
+ cy.get('[data-test=graphql-query-result]').should(($span) => {
52
+ const text = removeWhitespaces($span.text()); // remove all white spaces
53
+ expect(text).to.eq(
54
+ removeWhitespaces(`query{users(first:20,offset:20,
55
+ orderBy:[{field:"name",direction:ASC},{field:"company",direction:DESC}],
56
+ filterBy:[
57
+ {field:"gender",operator:EQ,value:"male"},
58
+ {field:"name",operator:StartsWith,value:"Joh"},{field:"name",operator:EndsWith,value:"oe"},
59
+ {field:"company",operator:IN,value:"xyz"},{field:"finish",operator:GE,value:"${presetLowestDay}"},{field:"finish",operator:LE,value:"${presetHighestDay}"}
60
+ ],locale:"en",userId:123){
61
+ totalCount,nodes{id,name,gender,company,billing{address{street,zip}},finish}}}`)
62
+ );
63
+ });
64
+ });
65
+
66
+ it('should use fake smaller server wait delay for faster E2E tests', () => {
67
+ cy.get('[data-test="server-delay"]').clear().type('20');
68
+ });
69
+
70
+ it('should change Pagination to next page', () => {
71
+ cy.get('.icon-seek-next').click();
72
+
73
+ // wait for the query to finish
74
+ cy.get('[data-test=status]').should('contain', 'finished');
75
+
76
+ cy.get('[data-test=graphql-query-result]').should(($span) => {
77
+ const text = removeWhitespaces($span.text()); // remove all white spaces
78
+ expect(text).to.eq(
79
+ removeWhitespaces(`query{users(first:20,offset:40,
80
+ orderBy:[{field:"name",direction:ASC},{field:"company",direction:DESC}],
81
+ filterBy:[
82
+ {field:"gender",operator:EQ,value:"male"},
83
+ {field:"name",operator:StartsWith,value:"Joh"},{field:"name",operator:EndsWith,value:"oe"},
84
+ {field:"company",operator:IN,value:"xyz"},{field:"finish",operator:GE,value:"${presetLowestDay}"},{field:"finish",operator:LE,value:"${presetHighestDay}"}
85
+ ],locale:"en",userId:123){totalCount,nodes{id,name,gender,company,billing{address{street,zip}},finish}}}`)
86
+ );
87
+ });
88
+ });
89
+
90
+ it('should change Pagination to last page', () => {
91
+ cy.get('.icon-seek-end').click();
92
+
93
+ // wait for the query to finish
94
+ cy.get('[data-test=status]').should('contain', 'finished');
95
+
96
+ cy.get('[data-test=graphql-query-result]').should(($span) => {
97
+ const text = removeWhitespaces($span.text()); // remove all white spaces
98
+ expect(text).to.eq(
99
+ removeWhitespaces(`query{users(first:20,offset:80,
100
+ orderBy:[{field:"name",direction:ASC},{field:"company",direction:DESC}],
101
+ filterBy:[
102
+ {field:"gender",operator:EQ,value:"male"},
103
+ {field:"name",operator:StartsWith,value:"Joh"},{field:"name",operator:EndsWith,value:"oe"},
104
+ {field:"company",operator:IN,value:"xyz"},{field:"finish",operator:GE,value:"${presetLowestDay}"},{field:"finish",operator:LE,value:"${presetHighestDay}"}
105
+ ],locale:"en",userId:123){totalCount,nodes{id,name,gender,company,billing{address{street,zip}},finish}}}`)
106
+ );
107
+ });
108
+ });
109
+
110
+ it('should change Pagination to first page using the external button', () => {
111
+ cy.get('[data-test=goto-first-page').click();
112
+
113
+ // wait for the query to finish
114
+ cy.get('[data-test=status]').should('contain', 'finished');
115
+
116
+ cy.get('[data-test=graphql-query-result]').should(($span) => {
117
+ const text = removeWhitespaces($span.text()); // remove all white spaces
118
+ expect(text).to.eq(
119
+ removeWhitespaces(`query { users (first:20,offset:0,
120
+ orderBy:[{field:"name",direction:ASC},{field:"company",direction:DESC}],
121
+ filterBy:[
122
+ {field:"gender",operator:EQ,value:"male"},
123
+ {field:"name",operator:StartsWith,value:"Joh"},{field:"name",operator:EndsWith,value:"oe"},
124
+ {field:"company",operator:IN,value:"xyz"},
125
+ {field:"finish",operator:GE,value:"${presetLowestDay}"},
126
+ {field:"finish",operator:LE,value:"${presetHighestDay}"}
127
+ ],locale:"en",userId:123) { totalCount, nodes { id,name,gender,company,billing{address{street,zip}},finish } } }`)
128
+ );
129
+ });
130
+ });
131
+
132
+ it('should change Pagination to last page using the external button', () => {
133
+ cy.get('[data-test=goto-last-page').click();
134
+
135
+ // wait for the query to finish
136
+ cy.get('[data-test=status]').should('contain', 'finished');
137
+
138
+ cy.get('[data-test=graphql-query-result]').should(($span) => {
139
+ const text = removeWhitespaces($span.text()); // remove all white spaces
140
+ expect(text).to.eq(
141
+ removeWhitespaces(`query{users(first:20,offset:80,
142
+ orderBy:[{field:"name",direction:ASC},{field:"company",direction:DESC}],
143
+ filterBy:[
144
+ {field:"gender",operator:EQ,value:"male"},
145
+ {field:"name",operator:StartsWith,value:"Joh"},{field:"name",operator:EndsWith,value:"oe"},
146
+ {field:"company",operator:IN,value:"xyz"},{field:"finish",operator:GE,value:"${presetLowestDay}"},{field:"finish",operator:LE,value:"${presetHighestDay}"}
147
+ ],locale:"en",userId:123){totalCount,nodes{id,name,gender,company,billing{address{street,zip}},finish}}}`)
148
+ );
149
+ });
150
+ });
151
+
152
+ it('should change Pagination to first page with 30 items', () => {
153
+ cy.get('.icon-seek-first').click();
154
+
155
+ cy.get('#items-per-page-label').select('30');
156
+
157
+ // wait for the query to finish
158
+ cy.get('[data-test=status]').should('contain', 'finished');
159
+
160
+ cy.get('[data-test=graphql-query-result]').should(($span) => {
161
+ const text = removeWhitespaces($span.text()); // remove all white spaces
162
+ expect(text).to.eq(
163
+ removeWhitespaces(`query{users(first:30,offset:0,
164
+ orderBy:[{field:"name",direction:ASC},{field:"company",direction:DESC}],
165
+ filterBy:[
166
+ {field:"gender",operator:EQ,value:"male"},
167
+ {field:"name",operator:StartsWith,value:"Joh"},{field:"name",operator:EndsWith,value:"oe"},
168
+ {field:"company",operator:IN,value:"xyz"},{field:"finish",operator:GE,value:"${presetLowestDay}"},{field:"finish",operator:LE,value:"${presetHighestDay}"}
169
+ ],locale:"en",userId:123){totalCount,nodes{id,name,gender,company,billing{address{street,zip}},finish}}}`)
170
+ );
171
+ });
172
+ });
173
+
174
+ it('should clear a single filter, that is not empty, by the header menu and expect query change', () => {
175
+ cy.get('#grid6')
176
+ .find('.slick-header-left .slick-header-column:nth(0)')
177
+ .trigger('mouseover')
178
+ .children('.slick-header-menu-button')
179
+ .should('be.hidden')
180
+ .invoke('show')
181
+ .click();
182
+
183
+ cy.get('.slick-header-menu .slick-menu-command-list')
184
+ .should('be.visible')
185
+ .children('.slick-menu-item:nth-of-type(6)')
186
+ .children('.slick-menu-content')
187
+ .should('contain', 'Remove Filter')
188
+ .click();
189
+
190
+ // wait for the query to finish
191
+ cy.get('[data-test=status]').should('contain', 'finished');
192
+
193
+ cy.get('[data-test=graphql-query-result]').should(($span) => {
194
+ const text = removeWhitespaces($span.text()); // remove all white spaces
195
+ expect(text).to.eq(
196
+ removeWhitespaces(`query{users(first:30,offset:0,
197
+ orderBy:[{field:"name",direction:ASC},{field:"company",direction:DESC}],
198
+ filterBy:[
199
+ {field:"gender",operator:EQ,value:"male"},{field:"company",operator:IN,value:"xyz"},
200
+ {field:"finish",operator:GE,value:"${presetLowestDay}"},{field:"finish",operator:LE,value:"${presetHighestDay}"}
201
+ ],locale:"en",userId:123){totalCount,nodes{id,name,gender,company,billing{address{street,zip}},finish}}}`)
202
+ );
203
+ });
204
+ });
205
+
206
+ it('should try clearing same filter, which is now empty, by the header menu and expect same query without loading spinner', () => {
207
+ cy.get('[data-test="server-delay"]').clear().type('250');
208
+
209
+ cy.get('#grid6')
210
+ .find('.slick-header-left .slick-header-column:nth(0)')
211
+ .trigger('mouseover')
212
+ .children('.slick-header-menu-button')
213
+ .invoke('show')
214
+ .click();
215
+
216
+ cy.get('.slick-header-menu .slick-menu-command-list')
217
+ .should('be.visible')
218
+ .children('.slick-menu-item:nth-of-type(6)')
219
+ .children('.slick-menu-content')
220
+ .should('contain', 'Remove Filter')
221
+ .click();
222
+
223
+ // wait for the query to finish
224
+ cy.get('[data-test=status]').should('contain', 'finished');
225
+
226
+ cy.get('[data-test=graphql-query-result]').should(($span) => {
227
+ const text = removeWhitespaces($span.text()); // remove all white spaces
228
+ expect(text).to.eq(
229
+ removeWhitespaces(`query{users(first:30,offset:0,
230
+ orderBy:[{field:"name",direction:ASC},{field:"company",direction:DESC}],
231
+ filterBy:[
232
+ {field:"gender",operator:EQ,value:"male"},{field:"company",operator:IN,value:"xyz"},
233
+ {field:"finish",operator:GE,value:"${presetLowestDay}"},{field:"finish",operator:LE,value:"${presetHighestDay}"}
234
+ ],locale:"en",userId:123){totalCount,nodes{id,name,gender,company,billing{address{street,zip}},finish}}}`)
235
+ );
236
+ });
237
+ });
238
+
239
+ it('should clear the date range filter expect the query to have the 2 "finish" (GE, LE) filters removed', () => {
240
+ cy.get('#grid6')
241
+ .find('.slick-header-left .slick-header-column:nth(5)')
242
+ .trigger('mouseover')
243
+ .children('.slick-header-menu-button')
244
+ .should('be.hidden')
245
+ .invoke('show')
246
+ .click();
247
+
248
+ cy.get('.slick-header-menu .slick-menu-command-list')
249
+ .should('be.visible')
250
+ .children('.slick-menu-item[data-command=clear-filter]')
251
+ .children('.slick-menu-content')
252
+ .should('contain', 'Remove Filter')
253
+ .click();
254
+
255
+ // wait for the query to finish
256
+ cy.get('[data-test=status]').should('contain', 'finished');
257
+
258
+ cy.get('[data-test=graphql-query-result]').should(($span) => {
259
+ const text = removeWhitespaces($span.text()); // remove all white spaces
260
+ expect(text).to.eq(
261
+ removeWhitespaces(`query{users(first:30,offset:0,
262
+ orderBy:[{field:"name",direction:ASC},{field:"company",direction:DESC}],
263
+ filterBy:[{field:"gender",operator:EQ,value:"male"},{field:"company",operator:IN,value:"xyz"}],
264
+ locale:"en",userId:123){totalCount,nodes{id,name,gender,company,billing{address{street,zip}},finish}}}`)
265
+ );
266
+ });
267
+ });
268
+
269
+ it('should Clear all Filters & Sorts', () => {
270
+ cy.contains('Clear all Filter & Sorts').click();
271
+
272
+ // wait for the query to finish
273
+ cy.get('[data-test=status]').should('contain', 'finished');
274
+
275
+ cy.get('[data-test=graphql-query-result]').should(($span) => {
276
+ const text = removeWhitespaces($span.text()); // remove all white spaces
277
+ expect(text).to.eq(
278
+ removeWhitespaces(
279
+ `query{users(first:30,offset:0,locale:"en",userId:123){totalCount,nodes{id,name,gender,company,billing{address{street,zip}},finish}}}`
280
+ )
281
+ );
282
+ });
283
+ });
284
+
285
+ it('should click on "Name" column to sort it Ascending', () => {
286
+ cy.get('.slick-header-columns').children('.slick-header-left .slick-header-column:nth(0)').click();
287
+
288
+ cy.get('.slick-header-columns')
289
+ .children('.slick-header-left .slick-header-column:nth(0)')
290
+ .find('.slick-sort-indicator.slick-sort-indicator-asc')
291
+ .should('be.visible');
292
+
293
+ // wait for the query to finish
294
+ cy.get('[data-test=status]').should('contain', 'finished');
295
+
296
+ cy.get('[data-test=graphql-query-result]').should(($span) => {
297
+ const text = removeWhitespaces($span.text()); // remove all white spaces
298
+ expect(text).to.eq(
299
+ removeWhitespaces(`query{users(first:30,offset:0,
300
+ orderBy:[{field:"name",direction:ASC}],
301
+ locale:"en",userId:123){totalCount,nodes{id,name,gender,company,billing{address{street,zip}},finish}}}`)
302
+ );
303
+ });
304
+ });
305
+
306
+ it('should perform filterQueryOverride when operator "%%" is selected', () => {
307
+ cy.get('.search-filter.filter-name select')
308
+ .find('option')
309
+ .last()
310
+ .then((element) => {
311
+ cy.get('.search-filter.filter-name select').select(element.val());
312
+ });
313
+
314
+ cy.get('.search-filter.filter-name').find('input').clear().type('Jo%yn%er');
315
+
316
+ // wait for the query to finish
317
+ cy.get('[data-test=status]').should('contain', 'finished');
318
+
319
+ cy.get('[data-test=graphql-query-result]').should(($span) => {
320
+ const text = removeSpaces($span.text()); // remove all white spaces
321
+ expect(text).to.eq(
322
+ removeSpaces(`query { users (first:30,offset:0,
323
+ orderBy:[{field:"name",direction:ASC}],
324
+ filterBy:[{field:"name",operator:Like,value:"Jo%yn%er"}],
325
+ locale:"en",userId:123) { totalCount, nodes { id,name,gender,company,billing{address{street,zip}},finish } } }`)
326
+ );
327
+ });
328
+ });
329
+
330
+ it('should click on Set Dynamic Filter and expect query and filters to be changed', () => {
331
+ cy.get('[data-test=set-dynamic-filter]').click();
332
+
333
+ cy.get('.search-filter.filter-name select').should('have.value', 'a*');
334
+
335
+ cy.get('.search-filter.filter-name')
336
+ .find('input')
337
+ .invoke('val')
338
+ .then((text) => expect(text).to.eq('Jane'));
339
+
340
+ cy.get('.search-filter.filter-gender .ms-choice > span').contains('Female');
341
+
342
+ cy.get('.search-filter.filter-company .ms-choice > span').contains('Acme');
343
+
344
+ cy.get('.search-filter.filter-billingAddressZip select').should('have.value', '>=');
345
+
346
+ cy.get('.search-filter.filter-billingAddressZip')
347
+ .find('input')
348
+ .invoke('val')
349
+ .then((text) => expect(text).to.eq('11'));
350
+
351
+ cy.get('.search-filter.filter-finish')
352
+ .find('input')
353
+ .invoke('val')
354
+ .then((text) => expect(text).to.eq(`${presetLowestDay} — ${presetHighestDay}`));
355
+
356
+ // wait for the query to finish
357
+ cy.get('[data-test=status]').should('contain', 'finished');
358
+
359
+ cy.get('[data-test=graphql-query-result]').should(($span) => {
360
+ const text = removeWhitespaces($span.text()); // remove all white spaces
361
+ expect(text).to.eq(
362
+ removeWhitespaces(`query{users(first:30,offset:0,
363
+ orderBy:[{field:"name",direction:ASC}],
364
+ filterBy:[{field:"gender",operator:EQ,value:"female"},{field:"name",operator:StartsWith,value:"Jane"},
365
+ {field:"company",operator:IN,value:"acme"},{field:"billing.address.zip",operator:GE,value:"11"},
366
+ {field:"finish",operator:GE,value:"${presetLowestDay}"},{field:"finish",operator:LE,value:"${presetHighestDay}"}],locale:"en",userId:123)
367
+ {totalCount,nodes{id,name,gender,company,billing{address{street,zip}},finish}}}`)
368
+ );
369
+ });
370
+ });
371
+
372
+ it('should use a range filter when searching with ".."', () => {
373
+ cy.get('.slick-header-columns').children('.slick-header-left .slick-header-column:nth(0)').contains('Name').click();
374
+
375
+ cy.get('.search-filter.filter-name').find('input').clear().type('Anthony Joyner..Ayers Hood');
376
+
377
+ // wait for the query to finish
378
+ cy.get('[data-test=status]').should('contain', 'finished');
379
+
380
+ cy.get('[data-test=graphql-query-result]').should(($span) => {
381
+ const text = removeWhitespaces($span.text()); // remove all white spaces
382
+ expect(text).to.eq(
383
+ removeWhitespaces(`query { users (first:30,offset:0,
384
+ orderBy:[{field:"name",direction:DESC}],
385
+ filterBy:[{field:"gender",operator:EQ,value:"female"},{field:"name",operator:GE,value:"Anthony Joyner"},{field:"name",operator:LE,value:"Ayers Hood"},
386
+ {field:"company",operator:IN,value:"acme"},{field:"billing.address.zip",operator:GE,value:"11"},
387
+ {field:"finish",operator:GE,value:"${presetLowestDay}"},{field:"finish",operator:LE,value:"${presetHighestDay}"}],locale:"en",userId:123)
388
+ {totalCount,nodes{id,name,gender,company,billing{address{street,zip}},finish}}}`)
389
+ );
390
+ });
391
+ });
392
+
393
+ it('should open Date picker and expect date range between 01-Jan to 15-Feb', () => {
394
+ cy.get('.search-filter.filter-finish.filled input').click({ force: true });
395
+
396
+ cy.get('.vc:visible');
397
+
398
+ cy.get('[data-vc="column"]:nth(0) [data-vc="month"]').should('have.text', 'January');
399
+
400
+ cy.get('[data-vc="column"]:nth(1) [data-vc="month"]').should('have.text', 'February');
401
+
402
+ cy.get('[data-vc="year"]:nth(0)').should('have.text', currentYear);
403
+
404
+ cy.get('.vc:visible [data-vc-date-selected] button').should('have.length', 46);
405
+
406
+ cy.get('.vc:visible [data-vc-date-selected]').first().should('have.text', '1');
407
+
408
+ cy.get('.vc:visible [data-vc-date-selected]').last().should('have.text', '15');
409
+ });
410
+
411
+ describe('Set Dynamic Sorting', () => {
412
+ it('should use slower server wait delay to test loading widget', () => {
413
+ cy.get('[data-test="server-delay"]').clear().type('250');
414
+ });
415
+
416
+ it('should click on "Clear all Filters & Sorting" then "Set Dynamic Sorting" buttons', () => {
417
+ cy.get('[data-test=clear-filters-sorting]').click();
418
+
419
+ cy.get('[data-test=status]').should('contain', 'processing');
420
+ cy.get('[data-test=status]').should('contain', 'finished');
421
+
422
+ cy.get('[data-test=set-dynamic-sorting]').click();
423
+
424
+ cy.get('[data-test=status]').should('contain', 'processing');
425
+ cy.get('[data-test=status]').should('contain', 'finished');
426
+ });
427
+
428
+ it('should use smaller server wait delay for faster E2E tests', () => {
429
+ cy.get('[data-test="server-delay"]').clear().type('20');
430
+ });
431
+
432
+ it('should expect the grid to be sorted by "Zip" descending then by "Company" ascending', () => {
433
+ cy.get('#grid6')
434
+ .get('.slick-header-left .slick-header-column:nth(2)')
435
+ .find('.slick-sort-indicator-asc')
436
+ .should('have.length', 1)
437
+ .siblings('.slick-sort-indicator-numbered')
438
+ .contains('2');
439
+
440
+ cy.get('#grid6')
441
+ .get('.slick-header-left .slick-header-column:nth(3)')
442
+ .find('.slick-sort-indicator-desc')
443
+ .should('have.length', 1)
444
+ .siblings('.slick-sort-indicator-numbered')
445
+ .contains('1');
446
+
447
+ cy.get('[data-test=graphql-query-result]').should(($span) => {
448
+ const text = removeWhitespaces($span.text()); // remove all white spaces
449
+ expect(text).to.eq(
450
+ removeWhitespaces(`query{users(first:30,offset:0,
451
+ orderBy:[{field:"billing.address.zip",direction:DESC},{field:"company",direction:ASC}],locale:"en",userId:123){
452
+ totalCount,nodes{id,name,gender,company,billing{address{street,zip}},finish}}}`)
453
+ );
454
+ });
455
+ });
456
+
457
+ it('should open Date picker and no longer expect date range selection in the picker', () => {
458
+ cy.get('.search-filter.filter-finish').should('not.have.class', 'filled').click();
459
+
460
+ cy.get('[data-vc="year"]:nth(0)').should('have.text', currentYear);
461
+
462
+ cy.get('.vc:visible').find('[data-vc-date-selected]').should('not.exist');
463
+ });
464
+ });
465
+
466
+ describe('Translate by Language', () => {
467
+ it('should Clear all Filters & Sorts', () => {
468
+ cy.contains('Clear all Filter & Sorts').click();
469
+
470
+ // wait for the query to finish
471
+ cy.get('[data-test=status]').should('contain', 'finished');
472
+ });
473
+
474
+ it('should have English Column Titles in the grid after switching locale', () => {
475
+ const expectedColumnTitles = ['Name', 'Gender', 'Company', 'Billing Address Zip', 'Billing Address Street', 'Date'];
476
+
477
+ cy.get('#grid6')
478
+ .find('.slick-header-left .slick-header-columns')
479
+ .children()
480
+ .each(($child, index) => expect($child.text()).to.eq(expectedColumnTitles[index]));
481
+ });
482
+
483
+ it('should have English Column Grouping Titles in the grid after switching locale', () => {
484
+ const expectedGroupTitles = ['Customer Information', 'Billing Information'];
485
+ cy.get('#grid6')
486
+ .find('.slick-preheader-panel .slick-header-columns')
487
+ .children()
488
+ .each(($child, index) => expect($child.text()).to.eq(expectedGroupTitles[index]));
489
+ });
490
+
491
+ it('should hover over the "Title" column header menu and expect all commands be displayed in English', () => {
492
+ cy.get('#grid6')
493
+ .find('.slick-header-columns.slick-header-columns-left .slick-header-column')
494
+ .first()
495
+ .trigger('mouseover')
496
+ .children('.slick-header-menu-button')
497
+ .invoke('show')
498
+ .click();
499
+
500
+ cy.get('.slick-header-menu .slick-menu-command-list')
501
+ .should('be.visible')
502
+ .children('.slick-menu-item:nth-of-type(3)')
503
+ .children('.slick-menu-content')
504
+ .should('contain', 'Sort Ascending');
505
+
506
+ cy.get('.slick-header-menu .slick-menu-command-list')
507
+ .children('.slick-menu-item:nth-of-type(4)')
508
+ .children('.slick-menu-content')
509
+ .should('contain', 'Sort Descending');
510
+
511
+ cy.get('.slick-header-menu .slick-menu-command-list')
512
+ .children('.slick-menu-item:nth-of-type(6)')
513
+ .children('.slick-menu-content')
514
+ .should('contain', 'Remove Filter');
515
+
516
+ cy.get('.slick-header-menu .slick-menu-command-list')
517
+ .children('.slick-menu-item:nth-of-type(7)')
518
+ .children('.slick-menu-content')
519
+ .should('contain', 'Remove Sort');
520
+
521
+ cy.get('.slick-header-menu .slick-menu-command-list')
522
+ .children('.slick-menu-item:nth-of-type(8)')
523
+ .children('.slick-menu-content')
524
+ .should('contain', 'Hide Column');
525
+ });
526
+
527
+ it('should open the Grid Menu and expect all commands be displayed in English', () => {
528
+ cy.get('#grid6').find('button.slick-grid-menu-button').trigger('click');
529
+
530
+ cy.get('.slick-grid-menu .slick-menu-title:nth(0)').contains('Commands');
531
+
532
+ cy.get('.slick-grid-menu .slick-menu-item:nth(0) > span').contains('Clear all Filters');
533
+
534
+ cy.get('.slick-grid-menu .slick-menu-item:nth(1) > span').contains('Clear all Sorting');
535
+
536
+ cy.get('.slick-grid-menu .slick-menu-title:nth(1)').contains('Columns');
537
+
538
+ cy.get('.slick-grid-menu .slick-column-picker-list li:nth(0)').contains('Customer Information - Name');
539
+
540
+ cy.get('.slick-grid-menu .slick-column-picker-list li:nth(1)').contains('Customer Information - Gender');
541
+
542
+ cy.get('.slick-grid-menu [data-dismiss=slick-grid-menu].close').click({ force: true });
543
+ });
544
+
545
+ it('should switch locale from English to French', () => {
546
+ cy.get('[data-test=selected-locale]').should('contain', 'en.json');
547
+
548
+ cy.get('[data-test=language-button]').click();
549
+
550
+ cy.get('[data-test=selected-locale]').should('contain', 'fr.json');
551
+ });
552
+
553
+ it('should have French Column Titles in the grid after switching locale', () => {
554
+ const expectedColumnTitles = ['Nom', 'Sexe', 'Compagnie', 'Code zip de facturation', 'Adresse de facturation', 'Date'];
555
+
556
+ cy.get('#grid6')
557
+ .find('.slick-header-left .slick-header-columns')
558
+ .children()
559
+ .each(($child, index) => expect($child.text()).to.eq(expectedColumnTitles[index]));
560
+ });
561
+
562
+ it('should have French Column Grouping Titles in the grid after switching locale', () => {
563
+ const expectedGroupTitles = ['Information Client', 'Information de Facturation'];
564
+ cy.get('#grid6')
565
+ .find('.slick-preheader-panel .slick-header-columns')
566
+ .children()
567
+ .each(($child, index) => expect($child.text()).to.eq(expectedGroupTitles[index]));
568
+ });
569
+
570
+ it('should display Pagination in French', () => {
571
+ cy.get('.slick-pagination-settings > span').contains('éléments par page');
572
+
573
+ cy.get('.page-info-from-to').contains('de');
574
+
575
+ cy.get('[data-test=item-from]').contains('1');
576
+
577
+ cy.get('[data-test=item-to]').contains('30');
578
+
579
+ cy.get('[data-test=total-items]').contains('100');
580
+
581
+ cy.get('.page-info-total-items').contains('éléments');
582
+ });
583
+
584
+ it('should hover over the "Title" column header menu and expect all commands be displayed in French', () => {
585
+ cy.get('#grid6')
586
+ .find('.slick-header-columns.slick-header-columns-left .slick-header-column')
587
+ .first()
588
+ .trigger('mouseover')
589
+ .children('.slick-header-menu-button')
590
+ .invoke('show')
591
+ .click();
592
+
593
+ cy.get('.slick-header-menu .slick-menu-command-list')
594
+ .should('be.visible')
595
+ .children('.slick-menu-item:nth-of-type(3)')
596
+ .children('.slick-menu-content')
597
+ .should('contain', 'Trier par ordre croissant');
598
+
599
+ cy.get('.slick-header-menu .slick-menu-command-list')
600
+ .children('.slick-menu-item:nth-of-type(4)')
601
+ .children('.slick-menu-content')
602
+ .should('contain', 'Trier par ordre décroissant');
603
+
604
+ cy.get('.slick-header-menu .slick-menu-command-list')
605
+ .children('.slick-menu-item:nth-of-type(6)')
606
+ .children('.slick-menu-content')
607
+ .should('contain', 'Supprimer le filtre');
608
+
609
+ cy.get('.slick-header-menu .slick-menu-command-list')
610
+ .children('.slick-menu-item:nth-of-type(7)')
611
+ .children('.slick-menu-content')
612
+ .should('contain', 'Supprimer le tri');
613
+
614
+ cy.get('.slick-header-menu .slick-menu-command-list')
615
+ .children('.slick-menu-item:nth-of-type(8)')
616
+ .children('.slick-menu-content')
617
+ .should('contain', 'Cacher la colonne');
618
+ });
619
+
620
+ it('should open the Grid Menu and expect all commands be displayed in French', () => {
621
+ cy.get('#grid6').find('button.slick-grid-menu-button').trigger('click');
622
+
623
+ cy.get('.slick-grid-menu .slick-menu-title:nth(0)').contains('Commandes');
624
+
625
+ cy.get('.slick-grid-menu .slick-menu-item:nth(0) > span').contains('Supprimer tous les filtres');
626
+
627
+ cy.get('.slick-grid-menu .slick-menu-item:nth(1) > span').contains('Supprimer tous les tris');
628
+
629
+ cy.get('.slick-grid-menu .slick-menu-title:nth(1)').contains('Colonnes');
630
+
631
+ cy.get('.slick-grid-menu .slick-column-picker-list li:nth(0)').contains('Information Client - Nom');
632
+
633
+ cy.get('.slick-grid-menu .slick-column-picker-list li:nth(1)').contains('Information Client - Sexe');
634
+
635
+ cy.get('.slick-grid-menu [data-dismiss=slick-grid-menu].close').click({ force: true });
636
+ });
637
+
638
+ it('should click on Set Dynamic Filter and expect query and filters to be changed', () => {
639
+ cy.get('[data-test=set-dynamic-filter]').click();
640
+
641
+ cy.get('.search-filter.filter-name select').should('have.value', 'a*');
642
+
643
+ cy.get('.search-filter.filter-name')
644
+ .find('input')
645
+ .invoke('val')
646
+ .then((text) => expect(text).to.eq('Jane'));
647
+
648
+ cy.get('.search-filter.filter-gender .ms-choice > span').contains('Féminin');
649
+
650
+ cy.get('.search-filter.filter-company .ms-choice > span').contains('Acme');
651
+
652
+ cy.get('.search-filter.filter-billingAddressZip select').should('have.value', '>=');
653
+
654
+ cy.get('.search-filter.filter-billingAddressZip')
655
+ .find('input')
656
+ .invoke('val')
657
+ .then((text) => expect(text).to.eq('11'));
658
+
659
+ cy.get('.search-filter.filter-finish')
660
+ .find('input')
661
+ .invoke('val')
662
+ .then((text) => expect(text).to.eq(`${presetLowestDay} — ${presetHighestDay}`));
663
+
664
+ // wait for the query to finish
665
+ cy.get('[data-test=status]').should('contain', 'finished');
666
+
667
+ cy.get('[data-test=graphql-query-result]').should(($span) => {
668
+ const text = removeWhitespaces($span.text()); // remove all white spaces
669
+ expect(text).to.eq(
670
+ removeWhitespaces(`query{users(first:30,offset:0,
671
+ filterBy:[{field:"gender",operator:EQ,value:"female"},{field:"name",operator:StartsWith,value:"Jane"},
672
+ {field:"company",operator:IN,value:"acme"},{field:"billing.address.zip",operator:GE,value:"11"},
673
+ {field:"finish",operator:GE,value:"${presetLowestDay}"},{field:"finish",operator:LE,value:"${presetHighestDay}"}],locale:"fr",userId:123)
674
+ {totalCount,nodes{id,name,gender,company,billing{address{street,zip}},finish}}}`)
675
+ );
676
+ });
677
+ });
678
+
679
+ it('should have French Text inside some of the Filters', () => {
680
+ cy.get('div.ms-filter.filter-gender').trigger('click');
681
+
682
+ cy.get('.ms-drop')
683
+ .contains('Masculin') // use regexp to avoid finding first Task 3 which is in fact Task 399
684
+ .click();
685
+
686
+ cy.get('.search-filter.filter-gender .ms-choice > span').contains('Masculin');
687
+ });
688
+
689
+ it('should switch locale to English', () => {
690
+ cy.get('[data-test=language-button]').click();
691
+
692
+ cy.get('[data-test=selected-locale]').should('contain', 'en.json');
693
+ });
694
+ });
695
+
696
+ describe('Cursor Pagination', () => {
697
+ it('should re-initialize grid for cursor pagination', () => {
698
+ cy.get('[data-test="reset-presets"]').click(); // reset to same original presets
699
+ cy.get('[data-test=cursor]').click();
700
+ cy.wait(1);
701
+
702
+ // the page number input should be a label now
703
+ cy.get('[data-test=page-number-label]').should('exist').should('have.text', '1');
704
+ });
705
+
706
+ it('should change Pagination to the last page', () => {
707
+ // Go to first page (if not already there)
708
+ cy.get('[data-test=goto-first-page').click();
709
+
710
+ cy.get('.icon-seek-end').click();
711
+
712
+ // wait for the query to finish
713
+ cy.get('[data-test=status]').should('contain', 'finished');
714
+ cy.get('[data-test=graphql-query-result]').should(($span) => {
715
+ const text = removeWhitespaces($span.text()); // remove all white spaces
716
+ expect(text).to.eq(
717
+ removeWhitespaces(`query{users(last:20,
718
+ orderBy:[{field:"name",direction:ASC},{field:"company",direction:DESC}],
719
+ filterBy:[
720
+ {field:"gender",operator:EQ,value:"male"},
721
+ {field:"name",operator:StartsWith,value:"Joh"},{field:"name",operator:EndsWith,value:"oe"},
722
+ {field:"company",operator:IN,value:"xyz"},{field:"finish",operator:GE,value:"${presetLowestDay}"},{field:"finish",operator:LE,value:"${presetHighestDay}"}
723
+ ],locale:"en",userId:123){totalCount,nodes{id,name,gender,company,billing{address{street,zip}},finish},pageInfo{hasNextPage,hasPreviousPage,endCursor,startCursor},edges{cursor}}}`)
724
+ );
725
+ });
726
+ });
727
+
728
+ it('should change Pagination to the first page', () => {
729
+ // Go to first page (if not already there)
730
+ cy.get('[data-test=goto-last-page').click();
731
+
732
+ cy.get('.icon-seek-first').click();
733
+
734
+ // wait for the query to finish
735
+ cy.get('[data-test=status]').should('contain', 'finished');
736
+ cy.get('[data-test=graphql-query-result]').should(($span) => {
737
+ const text = removeWhitespaces($span.text()); // remove all white spaces
738
+ expect(text).to.eq(
739
+ removeWhitespaces(`query{users(first:20,
740
+ orderBy:[{field:"name",direction:ASC},{field:"company",direction:DESC}],
741
+ filterBy:[
742
+ {field:"gender",operator:EQ,value:"male"},
743
+ {field:"name",operator:StartsWith,value:"Joh"},{field:"name",operator:EndsWith,value:"oe"},
744
+ {field:"company",operator:IN,value:"xyz"},{field:"finish",operator:GE,value:"${presetLowestDay}"},{field:"finish",operator:LE,value:"${presetHighestDay}"}
745
+ ],locale:"en",userId:123){totalCount,nodes{id,name,gender,company,billing{address{street,zip}},finish},pageInfo{hasNextPage,hasPreviousPage,endCursor,startCursor},edges{cursor}}}`)
746
+ );
747
+ });
748
+ });
749
+
750
+ it('should change Pagination to next page and all the way to the last', () => {
751
+ // Go to first page (if not already there)
752
+ cy.get('[data-test=goto-first-page').click();
753
+ cy.get('[data-test=status]').should('contain', 'finished');
754
+
755
+ // on page 1, click 4 times to get to page 5 (the last page)
756
+ cy.wrap([0, 1, 2, 3]).each((el, i) => {
757
+ cy.wait(25); // Avoid clicking too fast and hitting race conditions because of the setTimeout in the example page (this timeout should be greater than in the page)
758
+ cy.get('.icon-seek-next')
759
+ .click()
760
+ .then(() => {
761
+ // wait for the query to finish
762
+ cy.get('[data-test=status]').should('contain', 'finished');
763
+ cy.get('[data-test=graphql-query-result]').should(($span) => {
764
+ // First page is A-B
765
+ // first click is to get page after A-B
766
+ // => get first 20 after 'B'
767
+ const afterCursor = String.fromCharCode('B'.charCodeAt(0) + i);
768
+
769
+ const text = removeWhitespaces($span.text()); // remove all white spaces
770
+ expect(text).to.eq(
771
+ removeWhitespaces(`query{users(first:20,after:"${afterCursor}",
772
+ orderBy:[{field:"name",direction:ASC},{field:"company",direction:DESC}],
773
+ filterBy:[
774
+ {field:"gender",operator:EQ,value:"male"},
775
+ {field:"name",operator:StartsWith,value:"Joh"},{field:"name",operator:EndsWith,value:"oe"},
776
+ {field:"company",operator:IN,value:"xyz"},{field:"finish",operator:GE,value:"${presetLowestDay}"},{field:"finish",operator:LE,value:"${presetHighestDay}"}
777
+ ],locale:"en",userId:123){totalCount,nodes{id,name,gender,company,billing{address{street,zip}},finish},pageInfo{hasNextPage,hasPreviousPage,endCursor,startCursor},edges{cursor}}}`)
778
+ );
779
+ });
780
+ });
781
+ });
782
+ });
783
+
784
+ it('should change Pagination from the last page all the way to the first', () => {
785
+ // Go to last page (if not already there)
786
+ cy.get('[data-test=goto-last-page').click();
787
+
788
+ // on page 5 (last page), click 4 times to go to page 1
789
+ cy.wrap([0, 1, 2, 3]).each((el, i) => {
790
+ cy.wait(25); // Avoid clicking too fast and hitting race conditions because of the setTimeout in the example page (this timeout should be greater than in the page)
791
+ cy.get('.icon-seek-prev')
792
+ .click()
793
+ .then(() => {
794
+ // wait for the query to finish
795
+ cy.get('[data-test=status]').should('contain', 'finished');
796
+ cy.get('[data-test=graphql-query-result]').should(($span) => {
797
+ // Last page is E-F
798
+ // first click is to get page before E-F
799
+ // => get last 20 before 'E'
800
+ const beforeCursor = String.fromCharCode('E'.charCodeAt(0) - i);
801
+
802
+ const text = removeWhitespaces($span.text()); // remove all white spaces
803
+ expect(text).to.eq(
804
+ removeWhitespaces(`query{users(last:20,before:"${beforeCursor}",
805
+ orderBy:[{field:"name",direction:ASC},{field:"company",direction:DESC}],
806
+ filterBy:[
807
+ {field:"gender",operator:EQ,value:"male"},
808
+ {field:"name",operator:StartsWith,value:"Joh"},{field:"name",operator:EndsWith,value:"oe"},
809
+ {field:"company",operator:IN,value:"xyz"},{field:"finish",operator:GE,value:"${presetLowestDay}"},{field:"finish",operator:LE,value:"${presetHighestDay}"}
810
+ ],locale:"en",userId:123){totalCount,nodes{id,name,gender,company,billing{address{street,zip}},finish},pageInfo{hasNextPage,hasPreviousPage,endCursor,startCursor},edges{cursor}}}`)
811
+ );
812
+ });
813
+ });
814
+ });
815
+ });
816
+ });
817
+
818
+ describe('Filter Shortcuts', () => {
819
+ const today = format(new Date(), 'YYYY-MM-DD');
820
+ const next20Day = format(addDay(new Date(), 20), 'YYYY-MM-DD');
821
+
822
+ it('should open header menu of "Finish" again then choose "Filter Shortcuts -> In the Future" and expect date range of the next 20 days', () => {
823
+ cy.get('[data-test=offset]').click();
824
+
825
+ cy.get('#grid6')
826
+ .find('.slick-header-column:nth-of-type(6)')
827
+ .trigger('mouseover')
828
+ .children('.slick-header-menu-button')
829
+ .invoke('show')
830
+ .click();
831
+
832
+ cy.get('[data-command=filter-shortcuts-root-menu]').trigger('mouseover');
833
+
834
+ cy.get('.slick-header-menu.slick-menu-level-1').find('[data-command=next-20-days]').should('contain', 'Next 20 days').click();
835
+
836
+ cy.get('.search-filter.filter-finish input.date-picker').invoke('val').should('equal', `${today} — ${next20Day}`);
837
+
838
+ // wait for the query to finish
839
+ cy.get('[data-test=status]').should('contain', 'finished');
840
+
841
+ cy.get('[data-test=graphql-query-result]').should(($span) => {
842
+ const text = removeSpaces($span.text()); // remove all white spaces
843
+ expect(text).to.eq(
844
+ removeSpaces(`query { users (first:20,offset:0,orderBy:[{field:"name",direction:ASC},
845
+ {field:"company",direction:DESC}],filterBy:[{field:"gender",operator:EQ,value:"male"},
846
+ {field:"name",operator:StartsWith,value:"Joh"},{field:"name",operator:EndsWith,value:"oe"},
847
+ {field:"company",operator:IN,value:"xyz"},{field:"finish",operator:GE,value:"${today}"},
848
+ {field:"finish",operator:LE,value:"${next20Day}"}],locale:"en",userId:123) {
849
+ totalCount, nodes { id,name,gender,company,billing{address{street,zip}},finish}}}`)
850
+ );
851
+ });
852
+ });
853
+
854
+ it('should switch locale to French', () => {
855
+ cy.get('[data-test=language-button]').click();
856
+
857
+ cy.get('[data-test=selected-locale]').should('contain', 'fr.json');
858
+ });
859
+
860
+ it('should open header menu of "Finish" again now expect French translations "Filter Shortcuts -> In the Future" and expect date range of the next 20 days', () => {
861
+ cy.get('#grid6')
862
+ .find('.slick-header-column:nth-of-type(6)')
863
+ .trigger('mouseover')
864
+ .children('.slick-header-menu-button')
865
+ .invoke('show')
866
+ .click();
867
+
868
+ cy.get('[data-command=filter-shortcuts-root-menu]').should('contain', 'Raccourcis de filtre').trigger('mouseover');
869
+
870
+ cy.get('.slick-header-menu.slick-menu-level-1').find('[data-command=next-20-days]').should('contain', '20 prochain jours').click();
871
+
872
+ cy.get('.search-filter.filter-finish input.date-picker').invoke('val').should('equal', `${today} — ${next20Day}`);
873
+
874
+ // wait for the query to finish
875
+ cy.get('[data-test=status]').should('contain', 'finished');
876
+
877
+ cy.get('[data-test=graphql-query-result]').should(($span) => {
878
+ const text = removeSpaces($span.text()); // remove all white spaces
879
+ expect(text).to.eq(
880
+ removeSpaces(`query { users (first:20,offset:0,orderBy:[{field:"name",direction:ASC},
881
+ {field:"company",direction:DESC}],filterBy:[{field:"gender",operator:EQ,value:"male"},
882
+ {field:"name",operator:StartsWith,value:"Joh"},{field:"name",operator:EndsWith,value:"oe"},
883
+ {field:"company",operator:IN,value:"xyz"},{field:"finish",operator:GE,value:"${today}"},
884
+ {field:"finish",operator:LE,value:"${next20Day}"}],locale:"fr",userId:123) {
885
+ totalCount, nodes { id,name,gender,company,billing{address{street,zip}},finish}}}`)
886
+ );
887
+ });
888
+ });
889
+ });
890
+ });