@urbanos/react-discovery-ui 2.1.43

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 (316) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +118 -0
  3. package/lib/ReactDiscoveryUI.js +103 -0
  4. package/lib/ReactDiscoveryUI.scss +13 -0
  5. package/lib/assets/arrow.svg +6 -0
  6. package/lib/assets/blk-database.svg +48 -0
  7. package/lib/assets/chart.svg +1 -0
  8. package/lib/assets/down.png +0 -0
  9. package/lib/assets/down.svg +1 -0
  10. package/lib/assets/folder_icon.png +0 -0
  11. package/lib/assets/folder_icon.svg +1 -0
  12. package/lib/assets/ic_arrow.svg +15 -0
  13. package/lib/assets/loadingicon.svg +57 -0
  14. package/lib/assets/no_image.png +0 -0
  15. package/lib/assets/plus.png +0 -0
  16. package/lib/assets/plus.svg +1 -0
  17. package/lib/assets/user.svg +1 -0
  18. package/lib/auth/auth0-client-provider.js +37 -0
  19. package/lib/auth/auth0-client-provider.test.js +33 -0
  20. package/lib/auth/auth0-wrapper.js +155 -0
  21. package/lib/auth/auth0-wrapper.test.js +100 -0
  22. package/lib/components/auth0-login-zone/auth0-login-zone.js +147 -0
  23. package/lib/components/auth0-login-zone/auth0-login-zone.test.js +177 -0
  24. package/lib/components/auth0-login-zone/index.js +9 -0
  25. package/lib/components/code-editor/code-editor.css +173 -0
  26. package/lib/components/code-editor/code-editor.js +64 -0
  27. package/lib/components/code-editor/index.js +9 -0
  28. package/lib/components/collapsable-box/collapsable-box.js +81 -0
  29. package/lib/components/collapsable-box/collapsable-box.scss +39 -0
  30. package/lib/components/collapsable-box/collapsable-box.test.js +87 -0
  31. package/lib/components/collapsable-box/index.js +9 -0
  32. package/lib/components/data-card/data-card.js +63 -0
  33. package/lib/components/data-card/data-card.scss +93 -0
  34. package/lib/components/data-card/data-card.test.js +74 -0
  35. package/lib/components/data-card/index.js +9 -0
  36. package/lib/components/data-view/data-view.js +194 -0
  37. package/lib/components/data-view/data-view.scss +39 -0
  38. package/lib/components/data-view/data-view.test.js +155 -0
  39. package/lib/components/data-view/index.js +9 -0
  40. package/lib/components/dataset-api-doc/api-example.js +120 -0
  41. package/lib/components/dataset-api-doc/api-example.scss +84 -0
  42. package/lib/components/dataset-api-doc/api-example.test.js +88 -0
  43. package/lib/components/dataset-api-doc/dataset-api-doc.js +117 -0
  44. package/lib/components/dataset-api-doc/dataset-api-doc.scss +8 -0
  45. package/lib/components/dataset-api-doc/dataset-api-doc.test.js +42 -0
  46. package/lib/components/dataset-api-doc/index.js +9 -0
  47. package/lib/components/dataset-details/dataset-details.js +64 -0
  48. package/lib/components/dataset-details/dataset-details.scss +58 -0
  49. package/lib/components/dataset-details/dataset-details.test.js +38 -0
  50. package/lib/components/dataset-details/index.js +9 -0
  51. package/lib/components/dataset-dictionary/dataset-dictionary.js +127 -0
  52. package/lib/components/dataset-dictionary/dataset-dictionary.scss +42 -0
  53. package/lib/components/dataset-dictionary/dataset-dictionary.test.js +286 -0
  54. package/lib/components/dataset-dictionary/index.js +9 -0
  55. package/lib/components/dataset-list/dataset-list.js +22 -0
  56. package/lib/components/dataset-list/dataset-list.scss +9 -0
  57. package/lib/components/dataset-list/dataset-list.test.js +16 -0
  58. package/lib/components/dataset-list/index.js +9 -0
  59. package/lib/components/dataset-metadata/dataset-metadata.js +169 -0
  60. package/lib/components/dataset-metadata/dataset-metadata.scss +34 -0
  61. package/lib/components/dataset-metadata/dataset-metadata.test.js +24 -0
  62. package/lib/components/dataset-metadata/index.js +9 -0
  63. package/lib/components/dataset-preview/connector.js +26 -0
  64. package/lib/components/dataset-preview/dataset-preview.js +58 -0
  65. package/lib/components/dataset-preview/dataset-preview.scss +24 -0
  66. package/lib/components/dataset-preview/dataset-preview.test.js +34 -0
  67. package/lib/components/dataset-preview/index.js +9 -0
  68. package/lib/components/dataset-quality/dataset-quality.js +56 -0
  69. package/lib/components/dataset-quality/dataset-quality.scss +24 -0
  70. package/lib/components/dataset-quality/dataset-quality.test.js +34 -0
  71. package/lib/components/dataset-quality/index.js +9 -0
  72. package/lib/components/dataset-recommendations/connector.js +24 -0
  73. package/lib/components/dataset-recommendations/dataset-recommendations.js +47 -0
  74. package/lib/components/dataset-recommendations/dataset-recommendations.scss +17 -0
  75. package/lib/components/dataset-recommendations/dataset-recommendations.test.js +37 -0
  76. package/lib/components/dataset-recommendations/index.js +9 -0
  77. package/lib/components/detail-toggle-icon/detail-toggle-icon.js +41 -0
  78. package/lib/components/detail-toggle-icon/detail-toggle-icon.scss +13 -0
  79. package/lib/components/detail-toggle-icon/detail-toggle-icon.test.js +20 -0
  80. package/lib/components/detail-toggle-icon/index.js +9 -0
  81. package/lib/components/facet-list/facet-list.js +47 -0
  82. package/lib/components/facet-list/facet-list.scss +19 -0
  83. package/lib/components/facet-list/facet-list.test.js +94 -0
  84. package/lib/components/facet-list/index.js +9 -0
  85. package/lib/components/facet-sidebar/facet-sidebar.js +101 -0
  86. package/lib/components/facet-sidebar/facet-sidebar.scss +129 -0
  87. package/lib/components/facet-sidebar/facet-sidebar.test.js +93 -0
  88. package/lib/components/facet-sidebar/index.js +9 -0
  89. package/lib/components/generic-elements/alert-component/alert-component.js +51 -0
  90. package/lib/components/generic-elements/alert-component/alert-component.scss +26 -0
  91. package/lib/components/generic-elements/alert-component/alert-component.test.js +26 -0
  92. package/lib/components/generic-elements/alert-component/index.js +9 -0
  93. package/lib/components/generic-elements/arrow-button/arrow-button.js +30 -0
  94. package/lib/components/generic-elements/arrow-button/index.js +9 -0
  95. package/lib/components/generic-elements/auto-anchoring-popover/index.js +61 -0
  96. package/lib/components/generic-elements/back-button/back-button.js +14 -0
  97. package/lib/components/generic-elements/back-button/back-button.scss +14 -0
  98. package/lib/components/generic-elements/back-button/index.js +9 -0
  99. package/lib/components/generic-elements/call-to-action-button/call-to-action-button.js +118 -0
  100. package/lib/components/generic-elements/call-to-action-button/call-to-action-button.scss +19 -0
  101. package/lib/components/generic-elements/call-to-action-button/call-to-action-button.test.js +68 -0
  102. package/lib/components/generic-elements/call-to-action-button/index.js +9 -0
  103. package/lib/components/generic-elements/chart-icon/index.js +23 -0
  104. package/lib/components/generic-elements/checkbox/checkbox.js +50 -0
  105. package/lib/components/generic-elements/checkbox/checkbox.scss +44 -0
  106. package/lib/components/generic-elements/checkbox/checkbox.test.js +71 -0
  107. package/lib/components/generic-elements/checkbox/index.js +9 -0
  108. package/lib/components/generic-elements/error-component/error-component.js +21 -0
  109. package/lib/components/generic-elements/error-component/error-component.scss +16 -0
  110. package/lib/components/generic-elements/error-component/error-component.test.js +12 -0
  111. package/lib/components/generic-elements/error-component/index.js +9 -0
  112. package/lib/components/generic-elements/folder-icon/index.js +23 -0
  113. package/lib/components/generic-elements/generated-link/generated-link.js +25 -0
  114. package/lib/components/generic-elements/generated-link/index.js +13 -0
  115. package/lib/components/generic-elements/loading-element/index.js +9 -0
  116. package/lib/components/generic-elements/loading-element/loading-element.js +22 -0
  117. package/lib/components/generic-elements/loading-element/loading-element.scss +6 -0
  118. package/lib/components/generic-elements/loading-element/loading-element.test.js +11 -0
  119. package/lib/components/generic-elements/paginator/index.js +9 -0
  120. package/lib/components/generic-elements/paginator/paginator.js +84 -0
  121. package/lib/components/generic-elements/paginator/paginator.scss +38 -0
  122. package/lib/components/generic-elements/paginator/paginator.test.js +140 -0
  123. package/lib/components/generic-elements/plus-icon/index.js +21 -0
  124. package/lib/components/generic-elements/save-indicator/index.js +9 -0
  125. package/lib/components/generic-elements/save-indicator/save-indicator.js +39 -0
  126. package/lib/components/generic-elements/save-indicator/save-indicator.scss +31 -0
  127. package/lib/components/generic-elements/save-indicator/save-indicator.test.js +89 -0
  128. package/lib/components/generic-elements/search/index.js +9 -0
  129. package/lib/components/generic-elements/search/search.js +93 -0
  130. package/lib/components/generic-elements/search/search.scss +90 -0
  131. package/lib/components/generic-elements/search/search.test.js +41 -0
  132. package/lib/components/generic-elements/select/index.js +9 -0
  133. package/lib/components/generic-elements/select/select.js +44 -0
  134. package/lib/components/generic-elements/select/select.scss +22 -0
  135. package/lib/components/generic-elements/select/select.test.js +34 -0
  136. package/lib/components/generic-elements/share-link/index.js +9 -0
  137. package/lib/components/generic-elements/share-link/share-link.js +23 -0
  138. package/lib/components/generic-elements/share-link/share-link.scss +17 -0
  139. package/lib/components/generic-elements/share-link/share-link.test.js +28 -0
  140. package/lib/components/generic-elements/sql-icon/index.js +20 -0
  141. package/lib/components/generic-elements/tab-button/index.js +9 -0
  142. package/lib/components/generic-elements/tab-button/tab-button.js +25 -0
  143. package/lib/components/generic-elements/tab-button/tab-button.scss +27 -0
  144. package/lib/components/generic-elements/visualize-button/index.js +9 -0
  145. package/lib/components/generic-elements/visualize-button/visualize-button.js +37 -0
  146. package/lib/components/generic-elements/visualize-button/visualize-button.scss +14 -0
  147. package/lib/components/login-zone/connector.js +25 -0
  148. package/lib/components/login-zone/index.js +9 -0
  149. package/lib/components/login-zone/login-svgs-and-text.js +39 -0
  150. package/lib/components/login-zone/login-zone.js +21 -0
  151. package/lib/components/login-zone/login-zone.scss +115 -0
  152. package/lib/components/login-zone/login-zone.test.js +17 -0
  153. package/lib/components/login-zone/login.js +48 -0
  154. package/lib/components/login-zone/logout.js +39 -0
  155. package/lib/components/network-loading-element/connector.js +17 -0
  156. package/lib/components/network-loading-element/index.js +9 -0
  157. package/lib/components/network-loading-element/network-loading-element.js +23 -0
  158. package/lib/components/network-loading-element/network-loading-element.scss +21 -0
  159. package/lib/components/network-loading-element/network-loading-element.test.js +34 -0
  160. package/lib/components/organization/index.js +9 -0
  161. package/lib/components/organization/organization.js +27 -0
  162. package/lib/components/organization/organization.scss +32 -0
  163. package/lib/components/protected-route/protected-route.js +101 -0
  164. package/lib/components/protected-route/protected-route.scss +4 -0
  165. package/lib/components/protected-route/protected-route.test.js +63 -0
  166. package/lib/components/query-form/index.js +9 -0
  167. package/lib/components/query-form/query-form.js +262 -0
  168. package/lib/components/query-form/query-form.scss +167 -0
  169. package/lib/components/query-form/query-form.test.js +248 -0
  170. package/lib/components/recommendation-list/index.js +9 -0
  171. package/lib/components/recommendation-list/recommendation-list.js +72 -0
  172. package/lib/components/recommendation-list/recommendation-list.scss +61 -0
  173. package/lib/components/recommendation-list/recommendation-list.test.js +38 -0
  174. package/lib/components/remote-toggle/__snapshots__/remote-toggle.test.js.snap +3 -0
  175. package/lib/components/remote-toggle/index.js +13 -0
  176. package/lib/components/remote-toggle/remote-toggle.js +35 -0
  177. package/lib/components/remote-toggle/remote-toggle.scss +0 -0
  178. package/lib/components/remote-toggle/remote-toggle.test.js +10 -0
  179. package/lib/components/share/index.js +9 -0
  180. package/lib/components/share/share.js +109 -0
  181. package/lib/components/share/share.scss +66 -0
  182. package/lib/components/streaming-api-doc/index.js +9 -0
  183. package/lib/components/streaming-api-doc/streaming-api-doc.js +76 -0
  184. package/lib/components/streaming-api-doc/streaming-api-doc.scss +23 -0
  185. package/lib/components/streaming-api-doc/streaming-api-doc.test.js +24 -0
  186. package/lib/components/tooltip/index.js +9 -0
  187. package/lib/components/tooltip/tooltip.js +17 -0
  188. package/lib/components/tooltip/tooltip.scss +16 -0
  189. package/lib/components/tooltip/tooltip.test.js +19 -0
  190. package/lib/components/visualization-list-menu-item/index.js +9 -0
  191. package/lib/components/visualization-list-menu-item/visualization-list-menu-item.js +53 -0
  192. package/lib/components/visualization-list-menu-item/visualization-list-menu-item.scss +21 -0
  193. package/lib/components/visualization-list-menu-item/visualization-list-menu-item.test.js +42 -0
  194. package/lib/components/visualization-save-menu-item/index.js +9 -0
  195. package/lib/components/visualization-save-menu-item/visualization-save-menu-item.js +101 -0
  196. package/lib/components/visualization-save-menu-item/visualization-save-menu-item.scss +37 -0
  197. package/lib/components/visualization-save-menu-item/visualization-save-menu-item.test.js +185 -0
  198. package/lib/components/visualizations/geojson/connector.js +29 -0
  199. package/lib/components/visualizations/geojson/geojson-visualization.js +151 -0
  200. package/lib/components/visualizations/geojson/geojson-visualization.scss +24 -0
  201. package/lib/components/visualizations/geojson/geojson-visualization.test.js +238 -0
  202. package/lib/components/visualizations/geojson/index.js +9 -0
  203. package/lib/pages/apikey-view/apiKey-view.test.js +204 -0
  204. package/lib/pages/apikey-view/apikey-view.js +166 -0
  205. package/lib/pages/apikey-view/apikey-view.scss +340 -0
  206. package/lib/pages/apikey-view/connector.js +31 -0
  207. package/lib/pages/apikey-view/index.js +9 -0
  208. package/lib/pages/chart-view/chart-view.js +92 -0
  209. package/lib/pages/chart-view/chart-view.scss +35 -0
  210. package/lib/pages/chart-view/chart-view.test.js +206 -0
  211. package/lib/pages/chart-view/connector.js +30 -0
  212. package/lib/pages/chart-view/index.js +9 -0
  213. package/lib/pages/dataset-detail-view/connector.js +38 -0
  214. package/lib/pages/dataset-detail-view/dataset-detail-view-connector.test.js +42 -0
  215. package/lib/pages/dataset-detail-view/dataset-detail-view.js +99 -0
  216. package/lib/pages/dataset-detail-view/dataset-detail-view.scss +190 -0
  217. package/lib/pages/dataset-detail-view/dataset-detail-view.test.js +305 -0
  218. package/lib/pages/dataset-detail-view/index.js +9 -0
  219. package/lib/pages/dataset-list-view/connector.js +30 -0
  220. package/lib/pages/dataset-list-view/dataset-list-view.js +132 -0
  221. package/lib/pages/dataset-list-view/dataset-list-view.scss +242 -0
  222. package/lib/pages/dataset-list-view/dataset-list-view.test.js +162 -0
  223. package/lib/pages/dataset-list-view/index.js +9 -0
  224. package/lib/pages/dataset-view/connector.js +55 -0
  225. package/lib/pages/dataset-view/dataset-view-connector.test.js +78 -0
  226. package/lib/pages/dataset-view/dataset-view.js +175 -0
  227. package/lib/pages/dataset-view/dataset-view.scss +95 -0
  228. package/lib/pages/dataset-view/dataset-view.test.js +157 -0
  229. package/lib/pages/dataset-view/index.js +9 -0
  230. package/lib/pages/login-view/connector.js +25 -0
  231. package/lib/pages/login-view/index.js +9 -0
  232. package/lib/pages/login-view/login-view.js +83 -0
  233. package/lib/pages/login-view/login-view.scss +62 -0
  234. package/lib/pages/login-view/login-view.test.js +23 -0
  235. package/lib/pages/oauth-error-view/index.js +9 -0
  236. package/lib/pages/oauth-error-view/oauth-error-view.js +25 -0
  237. package/lib/pages/oauth-error-view/oauth-error-view.scss +13 -0
  238. package/lib/pages/oauth-error-view/oauth-error-view.test.js +13 -0
  239. package/lib/pages/oauth-view/connector.js +22 -0
  240. package/lib/pages/oauth-view/index.js +9 -0
  241. package/lib/pages/oauth-view/oauth-view.js +124 -0
  242. package/lib/pages/oauth-view/oauth-view.scss +7 -0
  243. package/lib/pages/oauth-view/oauth-view.test.js +195 -0
  244. package/lib/pages/query-view/connector.js +40 -0
  245. package/lib/pages/query-view/index.js +9 -0
  246. package/lib/pages/query-view/query-view.js +80 -0
  247. package/lib/pages/query-view/query-view.scss +39 -0
  248. package/lib/pages/query-view/query-view.test.js +104 -0
  249. package/lib/pages/user-profile-view/connector.js +39 -0
  250. package/lib/pages/user-profile-view/index.js +9 -0
  251. package/lib/pages/user-profile-view/user-profile-view.js +154 -0
  252. package/lib/pages/user-profile-view/user-profile-view.scss +81 -0
  253. package/lib/pages/user-profile-view/user-profile-view.test.js +129 -0
  254. package/lib/pages/visualization-view/connector.js +52 -0
  255. package/lib/pages/visualization-view/index.js +9 -0
  256. package/lib/pages/visualization-view/visualization-view-connector.test.js +62 -0
  257. package/lib/pages/visualization-view/visualization-view.js +128 -0
  258. package/lib/pages/visualization-view/visualization-view.scss +115 -0
  259. package/lib/pages/visualization-view/visualization-view.test.js +188 -0
  260. package/lib/routes.js +18 -0
  261. package/lib/search-params/search-params-manager.js +171 -0
  262. package/lib/search-params/search-params-manager.test.js +490 -0
  263. package/lib/store/actions.js +428 -0
  264. package/lib/store/dataset-selectors.js +47 -0
  265. package/lib/store/dataset-selectors.test.js +154 -0
  266. package/lib/store/query-selectors.js +53 -0
  267. package/lib/store/query-selectors.test.js +153 -0
  268. package/lib/store/reducers/index.js +20 -0
  269. package/lib/store/reducers/query-reducer.js +52 -0
  270. package/lib/store/reducers/query-reducer.test.js +89 -0
  271. package/lib/store/reducers/reducers.js +196 -0
  272. package/lib/store/reducers/reducers.test.js +309 -0
  273. package/lib/store/reducers/visualization-reducer.js +167 -0
  274. package/lib/store/reducers/visualization-reducer.test.js +426 -0
  275. package/lib/store/sagas/api-invoker.js +79 -0
  276. package/lib/store/sagas/api-invoker.test.js +139 -0
  277. package/lib/store/sagas/apiKey-saga.js +81 -0
  278. package/lib/store/sagas/apiKey-saga.test.js +57 -0
  279. package/lib/store/sagas/dataset-download-saga.js +43 -0
  280. package/lib/store/sagas/dataset-list-saga.js +49 -0
  281. package/lib/store/sagas/dataset-list-saga.test.js +72 -0
  282. package/lib/store/sagas/dataset-preview-saga.js +44 -0
  283. package/lib/store/sagas/dataset-query-saga.js +43 -0
  284. package/lib/store/sagas/dataset-recommendation-saga.js +40 -0
  285. package/lib/store/sagas/dataset-saga.js +50 -0
  286. package/lib/store/sagas/freestyle-query-saga.js +127 -0
  287. package/lib/store/sagas/freestyle-query-saga.test.js +145 -0
  288. package/lib/store/sagas/index.js +44 -0
  289. package/lib/store/sagas/login-saga.js +85 -0
  290. package/lib/store/sagas/login-saga.test.js +84 -0
  291. package/lib/store/sagas/logout-saga.js +96 -0
  292. package/lib/store/sagas/oauth-saga.js +78 -0
  293. package/lib/store/sagas/oauth-saga.test.js +51 -0
  294. package/lib/store/sagas/process-login-saga.js +62 -0
  295. package/lib/store/sagas/process-login-saga.test.js +83 -0
  296. package/lib/store/sagas/visualization-saga.js +371 -0
  297. package/lib/store/sagas/visualization-saga.test.js +388 -0
  298. package/lib/store/selectors.js +83 -0
  299. package/lib/store/visualization-selectors.js +85 -0
  300. package/lib/store/visualization-selectors.test.js +195 -0
  301. package/lib/styles/mixins.scss +117 -0
  302. package/lib/styles/variables.scss +41 -0
  303. package/lib/utils/file-type-utils.js +18 -0
  304. package/lib/utils/file-type-utils.test.js +29 -0
  305. package/lib/utils/geojson-utils.js +70 -0
  306. package/lib/utils/geojson-utils.test.js +129 -0
  307. package/lib/utils/http-clients.js +218 -0
  308. package/lib/utils/http-clients.test.js +88 -0
  309. package/lib/utils/index.js +34 -0
  310. package/lib/utils/modified-date-string-builder.js +29 -0
  311. package/lib/utils/modified-date-string-builder.test.js +93 -0
  312. package/lib/utils/query-string-builder.js +38 -0
  313. package/lib/utils/query-string-builder.test.js +33 -0
  314. package/lib/utils/recommendation-utils.js +12 -0
  315. package/lib/utils/recommendation-utils.test.js +9 -0
  316. package/package.json +172 -0
@@ -0,0 +1,195 @@
1
+ import {
2
+ isVisualizationSaveable,
3
+ dereferencedChart,
4
+ visualizationAllowedActions
5
+ } from './visualization-selectors'
6
+ import { getVisualizationDataSources } from './query-selectors'
7
+ import { cloneDeep } from 'lodash'
8
+
9
+ describe('visualizationSaveable', () => {
10
+ describe('with visualization set to saving', () => {
11
+ let state
12
+ beforeEach(() => {
13
+ state = {
14
+ visualization: {
15
+ saving: true
16
+ }
17
+ }
18
+ })
19
+ describe('and no dataset available', () => {
20
+ beforeEach(() => {
21
+ state.datasetReducer = { dataset: null }
22
+ })
23
+
24
+ it('returns false even if query text is available', () => {
25
+ state.queryReducer = { queryText: 'select * from stuff' }
26
+
27
+ expect(isVisualizationSaveable(state)).toBe(false)
28
+ })
29
+ })
30
+
31
+ describe('and dataset available', () => {
32
+ beforeEach(() => {
33
+ state.datasetReducer = { dataset: { systemName: 'stuff' } }
34
+ })
35
+
36
+ it('returns false even if queryText is not set', () => {
37
+ state.queryReducer = { queryText: '' }
38
+
39
+ expect(isVisualizationSaveable(state)).toBe(false)
40
+ })
41
+ })
42
+ })
43
+
44
+ describe('with visualization set to loading', () => {
45
+ let state
46
+ beforeEach(() => {
47
+ state = {
48
+ visualization: {
49
+ loading: true
50
+ }
51
+ }
52
+ })
53
+ describe('and no dataset available', () => {
54
+ beforeEach(() => {
55
+ state.datasetReducer = { dataset: null }
56
+ })
57
+
58
+ it('returns false even if query text is available', () => {
59
+ state.queryReducer = { queryText: 'select * from stuff' }
60
+
61
+ expect(isVisualizationSaveable(state)).toBe(false)
62
+ })
63
+ })
64
+
65
+ describe('and dataset available', () => {
66
+ beforeEach(() => {
67
+ state.datasetReducer = { dataset: { systemName: 'stuff' } }
68
+ })
69
+
70
+ it('returns false even if queryText is not set', () => {
71
+ state.queryReducer = { queryText: '' }
72
+
73
+ expect(isVisualizationSaveable(state)).toBe(false)
74
+ })
75
+ })
76
+ })
77
+
78
+ describe('with no visualization loading or saving status set', () => {
79
+ let state
80
+ beforeEach(() => {
81
+ state = {
82
+ visualization: {
83
+ loading: false,
84
+ saving: false
85
+ }
86
+ }
87
+ })
88
+
89
+ describe('and no dataset available', () => {
90
+ beforeEach(() => {
91
+ state.datasetReducer = { dataset: null }
92
+ })
93
+
94
+ it('returns false if query text is empty', () => {
95
+ state.queryReducer = { queryText: '' }
96
+
97
+ expect(isVisualizationSaveable(state)).toBe(false)
98
+ })
99
+
100
+ it('returns false if query text is undefined', () => {
101
+ state.queryReducer = {}
102
+
103
+ expect(isVisualizationSaveable(state)).toBe(false)
104
+ })
105
+
106
+ it('returns true if query text is available', () => {
107
+ state.queryReducer = { queryText: 'select * from stuff' }
108
+
109
+ expect(isVisualizationSaveable(state)).toBe(true)
110
+ })
111
+ })
112
+
113
+ describe('and dataset available', () => {
114
+ beforeEach(() => {
115
+ state.datasetReducer = { dataset: { systemName: 'stuff' } }
116
+ })
117
+
118
+ it('returns true if queryText is not set', () => {
119
+ state.queryReducer = { queryText: '' }
120
+
121
+ expect(isVisualizationSaveable(state)).toBe(true)
122
+ })
123
+ })
124
+ })
125
+ })
126
+
127
+ describe('dererencedChart', () => {
128
+ const queryDataRow = {
129
+ bob: 'bob\'s bob',
130
+ thing: 'bob\'s thing'
131
+ }
132
+ const plotlyData = [
133
+ {
134
+ type: 'scatter',
135
+ mode: 'markers',
136
+ x: ['bob\'s bob'],
137
+ xsrc: 'bob',
138
+ meta: { columnNames: { x: 'bob', y: 'thing' } },
139
+ y: ['bob\'s thing'],
140
+ ysrc: 'thing'
141
+ }
142
+ ]
143
+
144
+ let state, result, preDerefDataSources
145
+
146
+ beforeEach(() => {
147
+ state = {
148
+ queryReducer: { queryData: [queryDataRow] },
149
+ visualization: {
150
+ chart: {
151
+ data: plotlyData,
152
+ frames: [{ some: 'stuff' }],
153
+ layout: { more: 'stuff' }
154
+ }
155
+ }
156
+ }
157
+
158
+ preDerefDataSources = cloneDeep(getVisualizationDataSources(state))
159
+
160
+ result = dereferencedChart(state)
161
+ })
162
+
163
+ it('returns plotly data with cleared data values', () => {
164
+ const firstPlotData = plotlyData[0]
165
+ const expected = { ...state.visualization.chart, ...{ data: [{ ...firstPlotData, ...{ x: null, y: null } }] } }
166
+
167
+ expect(result).toEqual(expected)
168
+ })
169
+
170
+ it('does not mutate data sources', () => {
171
+ expect(getVisualizationDataSources(state)).toEqual(preDerefDataSources)
172
+ })
173
+ })
174
+
175
+ describe('visualizationAllowedActions', () => {
176
+ it('returns actions associated with existing visualization if one is in store', () => {
177
+ const state = {
178
+ visualization: {
179
+ visualization: {
180
+ allowedActions: [{ name: 'xxxx' }, { name: 'yyyy' }]
181
+ }
182
+ }
183
+ }
184
+
185
+ expect(visualizationAllowedActions(state)).toEqual(['xxxx', 'yyyy'])
186
+ })
187
+
188
+ it('returns only a create action when no actions are present in the store', () => {
189
+ const state = {
190
+ visualization: { visualization: {} }
191
+ }
192
+
193
+ expect(visualizationAllowedActions(state)).toEqual(['create'])
194
+ })
195
+ })
@@ -0,0 +1,117 @@
1
+ @import "./variables.scss";
2
+
3
+ @mixin flex-row() {
4
+ flex-direction: row;
5
+ justify-content: center;
6
+ }
7
+
8
+ @mixin flex-column() {
9
+ display: flex;
10
+ flex-direction: column;
11
+ justify-content: center;
12
+ }
13
+
14
+ @mixin custom-element() {
15
+ display: block;
16
+ }
17
+
18
+ @mixin link() {
19
+ color: $almost-black;
20
+ text-decoration: none;
21
+
22
+ &:hover {
23
+ text-decoration: underline;
24
+ color: $light-blue;
25
+ }
26
+ }
27
+
28
+ @mixin sub-link() {
29
+ color: $light-blue;
30
+ text-decoration: none;
31
+
32
+ &:hover {
33
+ text-decoration: underline;
34
+ color: $almost-black;
35
+ }
36
+ }
37
+
38
+ @mixin button($background-color: $dark-blue) {
39
+ background-color: $background-color;
40
+ text-decoration: none;
41
+ border-width: 0px;
42
+
43
+ &:hover {
44
+ color: white;
45
+ background-color: $almost-black;
46
+ text-decoration: underline;
47
+ cursor: pointer;
48
+ }
49
+ }
50
+
51
+ @mixin page-with-left-bar() {
52
+ @include custom-element();
53
+ $padding: 2rem;
54
+
55
+ height: calc(100% - (#{$padding} * 2));
56
+ min-width: $break-min;
57
+
58
+ padding: $padding;
59
+
60
+ .left-section {
61
+ width: 19%;
62
+ display: block;
63
+ float: left;
64
+ margin-right: 1%;
65
+ }
66
+
67
+ .right-section {
68
+ width: 80%;
69
+ display: block;
70
+ float: left;
71
+ margin-bottom: 2em !important;
72
+ }
73
+
74
+ @media only screen and (max-width: 600px) {
75
+ padding: 4%;
76
+ min-width: 92%;
77
+ display: block;
78
+ }
79
+ }
80
+
81
+ @mixin header() {
82
+ font-size: 1.7rem;
83
+ line-height: 2rem;
84
+ font-weight: bold;
85
+ }
86
+
87
+ @mixin header-medium() {
88
+ @include header();
89
+ font-size: 1.5rem;
90
+ }
91
+
92
+ @mixin header-small() {
93
+ @include header();
94
+ font-size: 1.3rem;
95
+ }
96
+
97
+ @mixin default-loading-icon() {
98
+ width: 5rem;
99
+ margin: 5rem auto;
100
+ }
101
+
102
+ @mixin menu-item-popover() {
103
+ .tab-button {
104
+ outline: none;
105
+ }
106
+
107
+ .popover {
108
+ margin-right: 0.5rem;
109
+ padding: 1rem;
110
+ border-radius: 0px;
111
+
112
+ box-shadow: 0px 5px 5px -3px $box-shadow-grey, 0px 8px 10px 1px $box-shadow-grey, 0px 3px 14px 2px $box-shadow-grey;
113
+
114
+ min-width: 20rem;
115
+ /* popover does not deal well with this missing */
116
+ }
117
+ }
@@ -0,0 +1,41 @@
1
+ $black: #000000;
2
+ $white: #ffffff;
3
+ $almost-black: #333;
4
+ $super-light-grey: #f7f7f7;
5
+ $header-grey: #ebedf0;
6
+ $light-grey: #d2d4d6;
7
+ $medium-grey: #97999c;
8
+ $dark-grey: #636466;
9
+ $csv-green: #8fd400;
10
+ $green: #71a702;
11
+ $error-color: #B80000;
12
+ $warning-background: #ffdbdd;
13
+ $light-blue: #00aeef;
14
+ $dark-blue: #0F64B3;
15
+
16
+ $box-shadow-grey: rgba(0, 0, 0, 0.2);
17
+
18
+ $super-light-gray: $super-light-grey;
19
+ $light-gray: $light-grey;
20
+ $medium-gray: $medium-grey;
21
+ $dark-gray: $dark-grey;
22
+
23
+ $column-width: 6.92rem;
24
+ $break-max: 1110px;
25
+ $break-min: 768px;
26
+ $above-max-break: "only screen and (min-width: #{$break-max})";
27
+ $below-min-break: "only screen and (max-width: #{$break-min})";
28
+
29
+ :export {
30
+ almostBlack: $almost-black;
31
+ superLightGrey: $super-light-grey;
32
+ headerGrey: $header-grey;
33
+ lightGrey: $light-grey;
34
+ mediumGrey: $medium-grey;
35
+ darkGrey: $dark-grey;
36
+ csvGreen: $csv-green;
37
+ green: $green;
38
+ errorColor: $error-color;
39
+ lightBlue: $light-blue;
40
+ aboveMaxBreak: unquote($above-max-break);
41
+ }
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getDefaultFormat = exports.containsFileType = void 0;
7
+ var FORMAT_OVERRIDES = {
8
+ gtfs: 'json'
9
+ };
10
+ var containsFileType = exports.containsFileType = function containsFileType(dataset, fileType) {
11
+ return dataset.fileTypes && dataset.fileTypes.map(function (type) {
12
+ return type.toLowerCase();
13
+ }).includes(fileType);
14
+ };
15
+ var getDefaultFormat = exports.getDefaultFormat = function getDefaultFormat(dataset) {
16
+ var format = dataset.fileTypes && dataset.fileTypes.length > 0 ? dataset.fileTypes[0].toLowerCase() : 'json';
17
+ return FORMAT_OVERRIDES[format] || format;
18
+ };
@@ -0,0 +1,29 @@
1
+ import { getDefaultFormat } from './file-type-utils'
2
+ describe('datasetUrl', () => {
3
+ it('returns the first file type downcased', () => {
4
+ const dataset = {
5
+ id: 'dataset_id',
6
+ sourceType: 'ingest',
7
+ fileTypes: ['A-Positive', 'ONEGATIVE']
8
+ }
9
+
10
+ expect(getDefaultFormat(dataset)).toBe('a-positive')
11
+ })
12
+
13
+ it('returns json as the format instead of gtfs', () => {
14
+ const dataset = {
15
+ id: 'dataset_id',
16
+ fileTypes: ['gtfs']
17
+ }
18
+
19
+ expect(getDefaultFormat(dataset)).toBe('json')
20
+ })
21
+
22
+ it('returns json when no file types are present', () => {
23
+ const dataset = {
24
+ id: 'dataset_id',
25
+ fileTypes: []
26
+ }
27
+ expect(getDefaultFormat(dataset)).toBe('json')
28
+ })
29
+ })
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _lodash = _interopRequireDefault(require("lodash"));
8
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
9
+ function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
10
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
11
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
12
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
13
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
14
+ function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
15
+ var determineBBox = function determineBBox(geoJsonData) {
16
+ return geoJsonData.bbox ? geoJsonData.bbox : calculateBBox(geoJsonData);
17
+ };
18
+ var calculateBBox = function calculateBBox(geoJsonData) {
19
+ var initial = {
20
+ minLong: 1000,
21
+ minLat: 1000,
22
+ maxLong: -1000,
23
+ maxLat: -1000
24
+ };
25
+ var bounds = _lodash.default.chain(geoJsonData.features).map(flattenCoordinateLists).flatten().reduce(getNewBounds, initial).value();
26
+ return [bounds.minLong, bounds.minLat, bounds.maxLong, bounds.maxLat];
27
+ };
28
+ var flattenCoordinateLists = function flattenCoordinateLists(feature) {
29
+ switch (feature.geometry.type) {
30
+ case 'MultiLineString':
31
+ return _lodash.default.flatten(feature.geometry.coordinates);
32
+ case 'LineString':
33
+ return feature.geometry.coordinates;
34
+ default:
35
+ return [];
36
+ }
37
+ };
38
+ var getNewBounds = function getNewBounds(bounds, coordinate) {
39
+ var long = coordinate[0];
40
+ var lat = coordinate[1];
41
+ return {
42
+ minLat: Math.min(lat, bounds.minLat),
43
+ maxLat: Math.max(lat, bounds.maxLat),
44
+ minLong: Math.min(long, bounds.minLong),
45
+ maxLong: Math.max(long, bounds.maxLong)
46
+ };
47
+ };
48
+ var isValidBBox = function isValidBBox(boundingBox) {
49
+ if (!boundingBox || boundingBox.length != 4) {
50
+ return false;
51
+ }
52
+ var _boundingBox = _slicedToArray(boundingBox, 4),
53
+ minLong = _boundingBox[0],
54
+ minLat = _boundingBox[1],
55
+ maxLong = _boundingBox[2],
56
+ maxLat = _boundingBox[3];
57
+ if (boundingBox.some(function (x) {
58
+ return x === null;
59
+ })) {
60
+ return false;
61
+ }
62
+ if (minLong > maxLong || minLat > maxLat || minLong < -180 || minLong > 180 || minLat < -90 || minLat > 90 || maxLong < -180 || maxLong > 180 || maxLat < -90 || maxLat > 90) {
63
+ return false;
64
+ }
65
+ return true;
66
+ };
67
+ var _default = exports.default = {
68
+ determineBBox: determineBBox,
69
+ isValidBBox: isValidBBox
70
+ };
@@ -0,0 +1,129 @@
1
+ import { GeoJsonUtils } from './'
2
+
3
+ describe('determine bounding box', () => {
4
+ it('returns bbox when present on the dataset', () => {
5
+ const bbox = [5, 4, 3, 2]
6
+ const geoJsonData = { bbox: bbox }
7
+
8
+ const result = GeoJsonUtils.determineBBox(geoJsonData)
9
+
10
+ expect(result).toEqual(bbox)
11
+ })
12
+
13
+ describe('when bbox is not present on the dataset', () => {
14
+ it('calculates bbox for multi-line strings', () => {
15
+ const geoJsonData = {
16
+ features: [
17
+ {
18
+ geometry: {
19
+ type: 'MultiLineString',
20
+ coordinates: [[[1, 2], [3, 4]], [[5, 8]]]
21
+ }
22
+ },
23
+ {
24
+ geometry: {
25
+ type: 'MultiLineString',
26
+ coordinates: [[[7, 6]]]
27
+ }
28
+ }
29
+ ]
30
+ }
31
+
32
+ const result = GeoJsonUtils.determineBBox(geoJsonData)
33
+
34
+ expect(result).toEqual([1, 2, 7, 8])
35
+ })
36
+
37
+ it('calculates bbox for singe-line strings', () => {
38
+ const geoJsonData = {
39
+ features: [{
40
+ geometry: {
41
+ type: 'LineString',
42
+ coordinates: [[1, 2], [3, 8]]
43
+ }
44
+ }, {
45
+ geometry: {
46
+ type: 'LineString',
47
+ coordinates: [[7, 4], [5, 6]]
48
+ }
49
+ }]
50
+ }
51
+
52
+ const result = GeoJsonUtils.determineBBox(geoJsonData)
53
+
54
+ expect(result).toEqual([1, 2, 7, 8])
55
+ })
56
+
57
+ it('calculates bbox for a mix of single and multi-line strings', () => {
58
+ const geoJsonData = {
59
+ features: [
60
+ {
61
+ geometry: {
62
+ type: 'LineString',
63
+ coordinates: [[1, -6], [3, 8]]
64
+ }
65
+ },
66
+ {
67
+ geometry: {
68
+ type: 'MultiLineString',
69
+ coordinates: [[[7, 6], [-1, 2]], [[5, 4], [10, 12]]]
70
+ }
71
+ }
72
+ ]
73
+ }
74
+
75
+ const result = GeoJsonUtils.determineBBox(geoJsonData)
76
+
77
+ expect(result).toEqual([-1, -6, 10, 12])
78
+ })
79
+ })
80
+ })
81
+
82
+ describe('is valid bounding box', () => {
83
+ it('returns false if bounding box is not provided', () => {
84
+ expect(GeoJsonUtils.isValidBBox()).toBe(false)
85
+ })
86
+
87
+ it('returns false if bounding box does not have right number of values', () => {
88
+ expect(GeoJsonUtils.isValidBBox([-180, -90, 180])).toBe(false)
89
+ expect(GeoJsonUtils.isValidBBox([-180, -90, 180, 90, -180])).toBe(false)
90
+ })
91
+
92
+ it('returns false if minLong is out of range', () => {
93
+ expect(GeoJsonUtils.isValidBBox([-190, -90, 180, 90])).toBe(false)
94
+ expect(GeoJsonUtils.isValidBBox([190, -90, 180, 90])).toBe(false)
95
+ })
96
+
97
+ it('returns false if minLat is out of range', () => {
98
+ expect(GeoJsonUtils.isValidBBox([-180, -90.1, 180, 90])).toBe(false)
99
+ expect(GeoJsonUtils.isValidBBox([-180, 90.5, 180, 90])).toBe(false)
100
+ })
101
+
102
+ it('returns false if maxLong is out of range', () => {
103
+ expect(GeoJsonUtils.isValidBBox([-180, -90, -180.5, 90])).toBe(false)
104
+ expect(GeoJsonUtils.isValidBBox([-180, -90, 180.2, 90])).toBe(false)
105
+ })
106
+
107
+ it('returns false if maxLat is out of range', () => {
108
+ expect(GeoJsonUtils.isValidBBox([-180, -90, 180, -90.5])).toBe(false)
109
+ expect(GeoJsonUtils.isValidBBox([-180, -90, 180, 90.2])).toBe(false)
110
+ })
111
+
112
+ it('returns false if minLong and maxLong are reversed', () => {
113
+ expect(GeoJsonUtils.isValidBBox([0, -90, -1, 90])).toBe(false)
114
+ })
115
+
116
+ it('returns false if minLat and maxLat are reversed', () => {
117
+ expect(GeoJsonUtils.isValidBBox([-180, 1, 180, 0])).toBe(false)
118
+ })
119
+
120
+ it('returns false if any value of the array is null', () => {
121
+ expect(GeoJsonUtils.isValidBBox([null, null, null, null])).toBe(false)
122
+ expect(GeoJsonUtils.isValidBBox([null, -90, 180, 90])).toBe(false)
123
+ expect(GeoJsonUtils.isValidBBox([-180, -90, null, 90])).toBe(false)
124
+ })
125
+
126
+ it('returns true if all values are in range', () => {
127
+ expect(GeoJsonUtils.isValidBBox([-180, -90, 180, 90])).toBe(true)
128
+ })
129
+ })