@looker/api-explorer 0.9.36 → 0.9.37

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 (268) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/dist/bundle.js +1 -1
  3. package/dist/bundle.js.map +1 -1
  4. package/e2e/MethodScene.spec.ts +80 -0
  5. package/e2e/diffScene.spec.ts +28 -20
  6. package/e2e/e2e.spec.ts +45 -7
  7. package/lib/ApiExplorer.js +17 -6
  8. package/lib/ApiExplorer.js.map +1 -1
  9. package/lib/components/DocMarkdown/DocMarkdown.js +3 -1
  10. package/lib/components/DocMarkdown/DocMarkdown.js.map +1 -1
  11. package/lib/components/DocSDKs/DocDeclarations.js +10 -15
  12. package/lib/components/DocSDKs/DocDeclarations.js.map +1 -1
  13. package/lib/components/SelectorContainer/ApiSpecSelector.js +3 -1
  14. package/lib/components/SelectorContainer/ApiSpecSelector.js.map +1 -1
  15. package/lib/components/SelectorContainer/SdkLanguageSelector.js +20 -21
  16. package/lib/components/SelectorContainer/SdkLanguageSelector.js.map +1 -1
  17. package/lib/components/SelectorContainer/SelectorContainer.js +4 -1
  18. package/lib/components/SelectorContainer/SelectorContainer.js.map +1 -1
  19. package/lib/components/SelectorContainer/utils.d.ts +2 -0
  20. package/lib/components/SelectorContainer/utils.js +32 -0
  21. package/lib/components/SelectorContainer/utils.js.map +1 -0
  22. package/lib/components/SideNav/SideNav.js +20 -9
  23. package/lib/components/SideNav/SideNav.js.map +1 -1
  24. package/lib/components/SideNav/SideNavMethods.js +7 -6
  25. package/lib/components/SideNav/SideNavMethods.js.map +1 -1
  26. package/lib/components/SideNav/SideNavTypes.js +5 -4
  27. package/lib/components/SideNav/SideNavTypes.js.map +1 -1
  28. package/lib/components/index.d.ts +0 -1
  29. package/lib/components/index.js +0 -8
  30. package/lib/components/index.js.map +1 -1
  31. package/lib/esm/ApiExplorer.js +19 -8
  32. package/lib/esm/ApiExplorer.js.map +1 -1
  33. package/lib/esm/components/DocMarkdown/DocMarkdown.js +3 -1
  34. package/lib/esm/components/DocMarkdown/DocMarkdown.js.map +1 -1
  35. package/lib/esm/components/DocSDKs/DocDeclarations.js +9 -14
  36. package/lib/esm/components/DocSDKs/DocDeclarations.js.map +1 -1
  37. package/lib/esm/components/SelectorContainer/ApiSpecSelector.js +3 -1
  38. package/lib/esm/components/SelectorContainer/ApiSpecSelector.js.map +1 -1
  39. package/lib/esm/components/SelectorContainer/SdkLanguageSelector.js +16 -18
  40. package/lib/esm/components/SelectorContainer/SdkLanguageSelector.js.map +1 -1
  41. package/lib/esm/components/SelectorContainer/SelectorContainer.js +5 -2
  42. package/lib/esm/components/SelectorContainer/SelectorContainer.js.map +1 -1
  43. package/lib/esm/components/SelectorContainer/utils.js +22 -0
  44. package/lib/esm/components/SelectorContainer/utils.js.map +1 -0
  45. package/lib/esm/components/SideNav/SideNav.js +20 -10
  46. package/lib/esm/components/SideNav/SideNav.js.map +1 -1
  47. package/lib/esm/components/SideNav/SideNavMethods.js +8 -7
  48. package/lib/esm/components/SideNav/SideNavMethods.js.map +1 -1
  49. package/lib/esm/components/SideNav/SideNavTypes.js +6 -5
  50. package/lib/esm/components/SideNav/SideNavTypes.js.map +1 -1
  51. package/lib/esm/components/index.js +0 -1
  52. package/lib/esm/components/index.js.map +1 -1
  53. package/lib/esm/routes/AppRouter.js +6 -4
  54. package/lib/esm/routes/AppRouter.js.map +1 -1
  55. package/lib/esm/scenes/DiffScene/DiffScene.js +9 -7
  56. package/lib/esm/scenes/DiffScene/DiffScene.js.map +1 -1
  57. package/lib/esm/scenes/DiffScene/DocDiff/DiffItem.js +3 -1
  58. package/lib/esm/scenes/DiffScene/DocDiff/DiffItem.js.map +1 -1
  59. package/lib/esm/scenes/DiffScene/DocDiff/DocDiff.js +4 -4
  60. package/lib/esm/scenes/DiffScene/DocDiff/DocDiff.js.map +1 -1
  61. package/lib/esm/scenes/ErrorDetailScene/ErrorDetailScene.js +31 -0
  62. package/lib/esm/scenes/ErrorDetailScene/ErrorDetailScene.js.map +1 -0
  63. package/lib/esm/scenes/ErrorDetailScene/index.js +2 -0
  64. package/lib/esm/scenes/ErrorDetailScene/index.js.map +1 -0
  65. package/lib/esm/scenes/MethodScene/MethodScene.js +28 -9
  66. package/lib/esm/scenes/MethodScene/MethodScene.js.map +1 -1
  67. package/lib/esm/{components → scenes/MethodScene/components}/DocResponses/DocResponseTypes.js +1 -1
  68. package/lib/esm/scenes/MethodScene/components/DocResponses/DocResponseTypes.js.map +1 -0
  69. package/lib/esm/scenes/MethodScene/components/DocResponses/DocResponses.js +73 -0
  70. package/lib/esm/scenes/MethodScene/components/DocResponses/DocResponses.js.map +1 -0
  71. package/lib/esm/{components → scenes/MethodScene/components}/DocResponses/index.js +0 -0
  72. package/lib/esm/scenes/MethodScene/components/DocResponses/index.js.map +1 -0
  73. package/lib/esm/{components → scenes/MethodScene/components}/DocResponses/utils.js +0 -0
  74. package/lib/esm/scenes/MethodScene/components/DocResponses/utils.js.map +1 -0
  75. package/lib/esm/scenes/MethodScene/components/index.js +1 -0
  76. package/lib/esm/scenes/MethodScene/components/index.js.map +1 -1
  77. package/lib/esm/scenes/MethodTagScene/MethodTagScene.js +38 -11
  78. package/lib/esm/scenes/MethodTagScene/MethodTagScene.js.map +1 -1
  79. package/lib/esm/scenes/TypeScene/TypeScene.js +3 -1
  80. package/lib/esm/scenes/TypeScene/TypeScene.js.map +1 -1
  81. package/lib/esm/scenes/TypeTagScene/TypeTagScene.js +37 -10
  82. package/lib/esm/scenes/TypeTagScene/TypeTagScene.js.map +1 -1
  83. package/lib/esm/scenes/index.js +1 -0
  84. package/lib/esm/scenes/index.js.map +1 -1
  85. package/lib/esm/scenes/utils/hooks/index.js +2 -0
  86. package/lib/esm/scenes/utils/hooks/index.js.map +1 -0
  87. package/lib/esm/scenes/utils/hooks/tagStoreSync.js +37 -0
  88. package/lib/esm/scenes/utils/hooks/tagStoreSync.js.map +1 -0
  89. package/lib/esm/scenes/utils/index.js +2 -0
  90. package/lib/esm/scenes/utils/index.js.map +1 -0
  91. package/lib/esm/state/settings/selectors.js +1 -0
  92. package/lib/esm/state/settings/selectors.js.map +1 -1
  93. package/lib/esm/state/settings/slice.js +6 -1
  94. package/lib/esm/state/settings/slice.js.map +1 -1
  95. package/lib/esm/utils/hooks/globalStoreSync.js +53 -0
  96. package/lib/esm/utils/hooks/globalStoreSync.js.map +1 -0
  97. package/lib/esm/utils/hooks/index.js +4 -0
  98. package/lib/esm/utils/hooks/index.js.map +1 -0
  99. package/lib/esm/utils/hooks/navigation.js +72 -0
  100. package/lib/esm/utils/hooks/navigation.js.map +1 -0
  101. package/lib/esm/utils/hooks/useQuery.js +9 -0
  102. package/lib/esm/utils/hooks/useQuery.js.map +1 -0
  103. package/lib/esm/utils/index.js +2 -1
  104. package/lib/esm/utils/index.js.map +1 -1
  105. package/lib/esm/utils/path.js +21 -0
  106. package/lib/esm/utils/path.js.map +1 -1
  107. package/lib/esm/utils/sdkLanguage.js +42 -0
  108. package/lib/esm/utils/sdkLanguage.js.map +1 -0
  109. package/lib/routes/AppRouter.d.ts +1 -2
  110. package/lib/routes/AppRouter.js +5 -3
  111. package/lib/routes/AppRouter.js.map +1 -1
  112. package/lib/scenes/DiffScene/DiffScene.d.ts +0 -2
  113. package/lib/scenes/DiffScene/DiffScene.js +8 -6
  114. package/lib/scenes/DiffScene/DiffScene.js.map +1 -1
  115. package/lib/scenes/DiffScene/DocDiff/DiffItem.js +3 -1
  116. package/lib/scenes/DiffScene/DocDiff/DiffItem.js.map +1 -1
  117. package/lib/scenes/DiffScene/DocDiff/DocDiff.js +4 -4
  118. package/lib/scenes/DiffScene/DocDiff/DocDiff.js.map +1 -1
  119. package/lib/scenes/ErrorDetailScene/ErrorDetailScene.d.ts +7 -0
  120. package/lib/scenes/ErrorDetailScene/ErrorDetailScene.js +47 -0
  121. package/lib/scenes/ErrorDetailScene/ErrorDetailScene.js.map +1 -0
  122. package/lib/scenes/ErrorDetailScene/index.d.ts +1 -0
  123. package/lib/scenes/ErrorDetailScene/index.js +14 -0
  124. package/lib/{components/DocResponses → scenes/ErrorDetailScene}/index.js.map +1 -1
  125. package/lib/scenes/MethodScene/MethodScene.js +23 -4
  126. package/lib/scenes/MethodScene/MethodScene.js.map +1 -1
  127. package/lib/{components → scenes/MethodScene/components}/DocResponses/DocResponseTypes.d.ts +2 -2
  128. package/lib/{components → scenes/MethodScene/components}/DocResponses/DocResponseTypes.js +2 -2
  129. package/lib/scenes/MethodScene/components/DocResponses/DocResponseTypes.js.map +1 -0
  130. package/lib/scenes/MethodScene/components/DocResponses/DocResponses.d.ts +9 -0
  131. package/lib/scenes/MethodScene/components/DocResponses/DocResponses.js +93 -0
  132. package/lib/scenes/MethodScene/components/DocResponses/DocResponses.js.map +1 -0
  133. package/lib/{components → scenes/MethodScene/components}/DocResponses/index.d.ts +0 -0
  134. package/lib/{components → scenes/MethodScene/components}/DocResponses/index.js +0 -0
  135. package/lib/scenes/MethodScene/components/DocResponses/index.js.map +1 -0
  136. package/lib/{components → scenes/MethodScene/components}/DocResponses/utils.d.ts +0 -0
  137. package/lib/{components → scenes/MethodScene/components}/DocResponses/utils.js +0 -0
  138. package/lib/scenes/MethodScene/components/DocResponses/utils.js.map +1 -0
  139. package/lib/scenes/MethodScene/components/index.d.ts +1 -0
  140. package/lib/scenes/MethodScene/components/index.js +8 -0
  141. package/lib/scenes/MethodScene/components/index.js.map +1 -1
  142. package/lib/scenes/MethodTagScene/MethodTagScene.js +42 -12
  143. package/lib/scenes/MethodTagScene/MethodTagScene.js.map +1 -1
  144. package/lib/scenes/TypeScene/TypeScene.js +3 -1
  145. package/lib/scenes/TypeScene/TypeScene.js.map +1 -1
  146. package/lib/scenes/TypeTagScene/TypeTagScene.js +41 -11
  147. package/lib/scenes/TypeTagScene/TypeTagScene.js.map +1 -1
  148. package/lib/scenes/index.d.ts +1 -0
  149. package/lib/scenes/index.js +8 -0
  150. package/lib/scenes/index.js.map +1 -1
  151. package/lib/scenes/utils/hooks/index.d.ts +1 -0
  152. package/lib/scenes/utils/hooks/index.js +14 -0
  153. package/lib/scenes/utils/hooks/index.js.map +1 -0
  154. package/lib/scenes/utils/hooks/tagStoreSync.d.ts +1 -0
  155. package/lib/scenes/utils/hooks/tagStoreSync.js +51 -0
  156. package/lib/scenes/utils/hooks/tagStoreSync.js.map +1 -0
  157. package/lib/scenes/utils/index.d.ts +1 -0
  158. package/lib/scenes/utils/index.js +14 -0
  159. package/lib/scenes/utils/index.js.map +1 -0
  160. package/lib/state/settings/selectors.d.ts +2 -1
  161. package/lib/state/settings/selectors.js +5 -1
  162. package/lib/state/settings/selectors.js.map +1 -1
  163. package/lib/state/settings/slice.d.ts +7 -1
  164. package/lib/state/settings/slice.js +6 -1
  165. package/lib/state/settings/slice.js.map +1 -1
  166. package/lib/test-data/index.d.ts +1 -0
  167. package/lib/test-data/index.js +14 -0
  168. package/lib/test-data/index.js.map +1 -1
  169. package/lib/test-data/sdkLanguages.d.ts +10 -0
  170. package/lib/test-data/sdkLanguages.js +19 -0
  171. package/lib/test-data/sdkLanguages.js.map +1 -0
  172. package/lib/utils/hooks/globalStoreSync.d.ts +1 -0
  173. package/lib/utils/hooks/globalStoreSync.js +67 -0
  174. package/lib/utils/hooks/globalStoreSync.js.map +1 -0
  175. package/lib/utils/hooks/index.d.ts +3 -0
  176. package/lib/utils/hooks/index.js +30 -0
  177. package/lib/utils/hooks/index.js.map +1 -0
  178. package/lib/utils/hooks/navigation.d.ts +11 -0
  179. package/lib/utils/hooks/navigation.js +83 -0
  180. package/lib/utils/hooks/navigation.js.map +1 -0
  181. package/lib/utils/hooks/useQuery.d.ts +1 -0
  182. package/lib/utils/hooks/useQuery.js +20 -0
  183. package/lib/utils/hooks/useQuery.js.map +1 -0
  184. package/lib/utils/index.d.ts +2 -1
  185. package/lib/utils/index.js +29 -1
  186. package/lib/utils/index.js.map +1 -1
  187. package/lib/utils/path.d.ts +4 -0
  188. package/lib/utils/path.js +32 -1
  189. package/lib/utils/path.js.map +1 -1
  190. package/lib/utils/sdkLanguage.d.ts +6 -0
  191. package/lib/utils/sdkLanguage.js +59 -0
  192. package/lib/utils/sdkLanguage.js.map +1 -0
  193. package/package.json +14 -14
  194. package/src/ApiExplorer.tsx +13 -8
  195. package/src/components/DocMarkdown/DocMarkdown.tsx +1 -1
  196. package/src/components/DocSDKs/DocDeclarations.tsx +11 -22
  197. package/src/components/DocSDKs/DocSDKs.spec.tsx +4 -1
  198. package/src/components/Header/Header.spec.tsx +1 -1
  199. package/src/components/SelectorContainer/ApiSpecSelector.tsx +1 -1
  200. package/src/components/SelectorContainer/SdkLanguageSelector.spec.tsx +60 -33
  201. package/src/components/SelectorContainer/SdkLanguageSelector.tsx +15 -22
  202. package/src/components/SelectorContainer/SelectorContainer.spec.tsx +1 -1
  203. package/src/components/SelectorContainer/SelectorContainer.tsx +18 -15
  204. package/src/{utils/hooks.ts → components/SelectorContainer/utils.ts} +13 -21
  205. package/src/components/SideNav/SideNav.tsx +26 -14
  206. package/src/components/SideNav/SideNavMethods.spec.tsx +6 -8
  207. package/src/components/SideNav/SideNavMethods.tsx +8 -12
  208. package/src/components/SideNav/SideNavTypes.tsx +5 -10
  209. package/src/components/index.ts +0 -1
  210. package/src/routes/AppRouter.tsx +7 -5
  211. package/src/scenes/DiffScene/DiffScene.tsx +8 -8
  212. package/src/scenes/DiffScene/DocDiff/DiffItem.tsx +1 -1
  213. package/src/scenes/DiffScene/DocDiff/DocDiff.spec.tsx +73 -2
  214. package/src/scenes/DiffScene/DocDiff/DocDiff.tsx +4 -4
  215. package/src/scenes/ErrorDetailScene/ErrorDetailScene.tsx +72 -0
  216. package/src/scenes/ErrorDetailScene/index.ts +26 -0
  217. package/src/scenes/MethodScene/MethodScene.tsx +21 -7
  218. package/src/{components → scenes/MethodScene/components}/DocResponses/DocResponseTypes.tsx +3 -6
  219. package/src/scenes/MethodScene/components/DocResponses/DocResponses.spec.tsx +153 -0
  220. package/src/scenes/MethodScene/components/DocResponses/DocResponses.tsx +103 -0
  221. package/src/{components → scenes/MethodScene/components}/DocResponses/index.ts +0 -0
  222. package/src/{components → scenes/MethodScene/components}/DocResponses/utils.spec.ts +1 -1
  223. package/src/{components → scenes/MethodScene/components}/DocResponses/utils.ts +0 -0
  224. package/src/scenes/MethodScene/components/index.ts +1 -0
  225. package/src/scenes/MethodTagScene/MethodTagScene.spec.tsx +25 -14
  226. package/src/scenes/MethodTagScene/MethodTagScene.tsx +42 -11
  227. package/src/scenes/TypeScene/TypeScene.tsx +1 -1
  228. package/src/scenes/TypeTagScene/TypeTagScene.spec.tsx +21 -11
  229. package/src/scenes/TypeTagScene/TypeTagScene.tsx +44 -11
  230. package/src/scenes/index.ts +1 -0
  231. package/src/scenes/utils/hooks/index.ts +27 -0
  232. package/src/scenes/utils/hooks/tagStoreSync.spec.ts +102 -0
  233. package/src/scenes/utils/hooks/tagStoreSync.ts +68 -0
  234. package/src/scenes/utils/index.ts +27 -0
  235. package/src/state/settings/selectors.spec.ts +5 -1
  236. package/src/state/settings/selectors.ts +3 -0
  237. package/src/state/settings/slice.ts +6 -0
  238. package/src/test-data/index.ts +1 -0
  239. package/src/test-data/sdkLanguages.ts +36 -0
  240. package/src/utils/hooks/globalStoreSync.spec.tsx +146 -0
  241. package/src/utils/hooks/globalStoreSync.ts +77 -0
  242. package/src/utils/hooks/index.ts +28 -0
  243. package/src/utils/hooks/navigation.spec.ts +118 -0
  244. package/src/utils/hooks/navigation.ts +121 -0
  245. package/src/utils/hooks/useQuery.ts +36 -0
  246. package/src/utils/index.ts +2 -1
  247. package/src/utils/path.spec.ts +67 -1
  248. package/src/utils/path.ts +35 -0
  249. package/src/utils/sdkLanguage.spec.ts +69 -0
  250. package/src/utils/sdkLanguage.ts +63 -0
  251. package/lib/components/DocResponses/DocResponseTypes.js.map +0 -1
  252. package/lib/components/DocResponses/DocResponses.d.ts +0 -8
  253. package/lib/components/DocResponses/DocResponses.js +0 -46
  254. package/lib/components/DocResponses/DocResponses.js.map +0 -1
  255. package/lib/components/DocResponses/utils.js.map +0 -1
  256. package/lib/esm/components/DocResponses/DocResponseTypes.js.map +0 -1
  257. package/lib/esm/components/DocResponses/DocResponses.js +0 -30
  258. package/lib/esm/components/DocResponses/DocResponses.js.map +0 -1
  259. package/lib/esm/components/DocResponses/index.js.map +0 -1
  260. package/lib/esm/components/DocResponses/utils.js.map +0 -1
  261. package/lib/esm/utils/hooks.js +0 -26
  262. package/lib/esm/utils/hooks.js.map +0 -1
  263. package/lib/utils/hooks.d.ts +0 -3
  264. package/lib/utils/hooks.js +0 -36
  265. package/lib/utils/hooks.js.map +0 -1
  266. package/src/components/DocResponses/DocResponses.spec.tsx +0 -60
  267. package/src/components/DocResponses/DocResponses.tsx +0 -69
  268. package/src/utils/hooks.spec.ts +0 -78
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@looker/api-explorer",
3
- "version": "0.9.36",
3
+ "version": "0.9.37",
4
4
  "description": "Looker API Explorer",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib/esm/index.js",
@@ -32,12 +32,13 @@
32
32
  "deploy-dev-portal": "rm -f ../../../developer-portal/static/apix/dist/*.js* && cp -R ./dist/*.js* ../../../developer-portal/static/apix/dist"
33
33
  },
34
34
  "devDependencies": {
35
- "@looker/components-test-utils": "^1.5.5",
36
- "@looker/sdk-codegen-scripts": "^21.4.2",
37
- "@looker/sdk-node": "^22.10.1",
35
+ "@looker/components-test-utils": "^1.5.26",
36
+ "@looker/sdk-codegen-scripts": "^21.4.3",
37
+ "@looker/sdk-node": "^22.12.1",
38
38
  "@styled-icons/styled-icon": "^10.6.3",
39
39
  "@testing-library/jest-dom": "^5.11.6",
40
40
  "@testing-library/react": "^11.2.2",
41
+ "@testing-library/react-hooks": "^8.0.1",
41
42
  "@testing-library/user-event": "^12.6.0",
42
43
  "@types/expect-puppeteer": "^4.4.6",
43
44
  "@types/jest-environment-puppeteer": "^4.4.1",
@@ -67,17 +68,16 @@
67
68
  "webpack-merge": "^5.7.3"
68
69
  },
69
70
  "dependencies": {
70
- "@looker/code-editor": "^0.1.23",
71
- "@looker/components": "^2.8.1",
72
- "@looker/components-date": "^2.4.1",
73
- "@looker/design-tokens": "^2.7.1",
74
- "@looker/extension-utils": "^0.1.13",
71
+ "@looker/code-editor": "^0.1.24",
72
+ "@looker/components": "^3.0.8",
73
+ "@looker/design-tokens": "^2.7.21",
74
+ "@looker/extension-utils": "^0.1.14",
75
75
  "@looker/icons": "^1.5.3",
76
76
  "@looker/redux": "0.0.0",
77
- "@looker/run-it": "^0.9.36",
78
- "@looker/sdk": "^22.10.1",
79
- "@looker/sdk-codegen": "^21.7.0",
80
- "@looker/sdk-rtl": "^21.3.4",
77
+ "@looker/run-it": "^0.9.37",
78
+ "@looker/sdk": "^22.12.1",
79
+ "@looker/sdk-codegen": "^21.7.1",
80
+ "@looker/sdk-rtl": "^21.4.0",
81
81
  "@reduxjs/toolkit": "^1.6.2",
82
82
  "@styled-icons/material": "^10.28.0",
83
83
  "@styled-icons/material-outlined": "^10.28.0",
@@ -96,5 +96,5 @@
96
96
  "ts-jest": "^26.2.0",
97
97
  "typed-redux-saga": "^1.3.1"
98
98
  },
99
- "gitHead": "a3eb0fd43de195627b1723faae1eba7c70fd43fb"
99
+ "gitHead": "028fb6cd1f84c23fd10d42041f3d572f4f724195"
100
100
  }
@@ -60,15 +60,15 @@ import { AppRouter } from './routes'
60
60
  import { apixFilesHost } from './utils/lodeUtils'
61
61
  import {
62
62
  useSettingActions,
63
- useSettingStoreState,
64
63
  useLodeActions,
65
64
  useLodesStoreState,
66
65
  useSpecActions,
67
66
  useSpecStoreState,
68
67
  selectSpecs,
69
68
  selectCurrentSpec,
69
+ useSettingStoreState,
70
70
  } from './state'
71
- import { getSpecKey, diffPath } from './utils'
71
+ import { getSpecKey, findSdk, useGlobalStoreSync } from './utils'
72
72
 
73
73
  export interface ApiExplorerProps {
74
74
  adaptor: IApixAdaptor
@@ -85,16 +85,18 @@ export const ApiExplorer: FC<ApiExplorerProps> = ({
85
85
  declarationsLodeUrl = `${apixFilesHost}/declarationsIndex.json`,
86
86
  headless = false,
87
87
  }) => {
88
- useSettingStoreState()
89
88
  useLodesStoreState()
90
89
  const { working, description } = useSpecStoreState()
91
90
  const specs = useSelector(selectSpecs)
92
91
  const spec = useSelector(selectCurrentSpec)
93
92
  const { initLodesAction } = useLodeActions()
94
- const { initSettingsAction, setSearchPatternAction } = useSettingActions()
93
+ const { initialized } = useSettingStoreState()
94
+ const { initSettingsAction, setSearchPatternAction, setSdkLanguageAction } =
95
+ useSettingActions()
95
96
  const { initSpecsAction, setCurrentSpecAction } = useSpecActions()
96
97
 
97
98
  const location = useLocation()
99
+ useGlobalStoreSync()
98
100
  const [hasNavigation, setHasNavigation] = useState(true)
99
101
  const toggleNavigation = (target?: boolean) =>
100
102
  setHasNavigation(target || !hasNavigation)
@@ -118,15 +120,19 @@ export const ApiExplorer: FC<ApiExplorerProps> = ({
118
120
 
119
121
  useEffect(() => {
120
122
  const maybeSpec = location.pathname?.split('/')[1]
121
- if (spec && maybeSpec && maybeSpec !== diffPath && maybeSpec !== spec.key) {
123
+ if (spec && maybeSpec && maybeSpec !== spec.key) {
122
124
  setCurrentSpecAction({ currentSpecKey: maybeSpec })
123
125
  }
124
126
  }, [location.pathname, spec])
125
127
 
126
128
  useEffect(() => {
129
+ if (!initialized) return
127
130
  const searchParams = new URLSearchParams(location.search)
128
131
  const searchPattern = searchParams.get('s') || ''
129
- setSearchPatternAction({ searchPattern: searchPattern! })
132
+ const sdkParam = searchParams.get('sdk') || 'all'
133
+ const { language: sdkLanguage } = findSdk(sdkParam)
134
+ setSearchPatternAction({ searchPattern })
135
+ setSdkLanguageAction({ sdkLanguage })
130
136
  }, [location.search])
131
137
 
132
138
  useEffect(() => {
@@ -143,7 +149,7 @@ export const ApiExplorer: FC<ApiExplorerProps> = ({
143
149
  const themeOverrides = adaptor.themeOverrides()
144
150
 
145
151
  let neededSpec = location.pathname?.split('/')[1]
146
- if (!neededSpec || neededSpec === diffPath) {
152
+ if (!neededSpec) {
147
153
  neededSpec = spec?.key
148
154
  }
149
155
 
@@ -213,7 +219,6 @@ export const ApiExplorer: FC<ApiExplorerProps> = ({
213
219
  <AppRouter
214
220
  specKey={spec.key}
215
221
  api={spec.api!}
216
- specs={specs}
217
222
  toggleNavigation={toggleNavigation}
218
223
  />
219
224
  </Layout>
@@ -40,7 +40,7 @@ interface DocMarkdownProps {
40
40
 
41
41
  export const DocMarkdown: FC<DocMarkdownProps> = ({ source, specKey }) => {
42
42
  const searchPattern = useSelector(selectSearchPattern)
43
- const navigate = useNavigation()
43
+ const { navigate } = useNavigation()
44
44
 
45
45
  const linkClickHandler = (pathname: string, url: string) => {
46
46
  if (pathname.startsWith(`/${specKey}`)) {
@@ -23,10 +23,10 @@
23
23
  SOFTWARE.
24
24
 
25
25
  */
26
- import { Tab, TabList, TabPanel, TabPanels, useTabs } from '@looker/components'
26
+ import React from 'react'
27
+ import { Tab2, Tabs2 } from '@looker/components'
27
28
  import type { KeyedCollection } from '@looker/sdk-codegen'
28
29
  import type { FC } from 'react'
29
- import React from 'react'
30
30
  import { DocCode } from '../DocCode'
31
31
 
32
32
  interface DocDeclarationsProps {
@@ -37,23 +37,12 @@ interface DocDeclarationsProps {
37
37
  * Renders all provided declarations
38
38
  * @param declarations A collection of SDK declarations in various languages
39
39
  */
40
- export const DocDeclarations: FC<DocDeclarationsProps> = ({ declarations }) => {
41
- const tabs = useTabs()
42
-
43
- return (
44
- <>
45
- <TabList {...tabs}>
46
- {Object.keys(declarations).map((language) => (
47
- <Tab key={language}>{language}</Tab>
48
- ))}
49
- </TabList>
50
- <TabPanels {...tabs} pt="0">
51
- {Object.entries(declarations).map(([language, code]) => (
52
- <TabPanel key={language}>
53
- <DocCode language={language} code={code} />
54
- </TabPanel>
55
- ))}
56
- </TabPanels>
57
- </>
58
- )
59
- }
40
+ export const DocDeclarations: FC<DocDeclarationsProps> = ({ declarations }) => (
41
+ <Tabs2>
42
+ {Object.entries(declarations).map(([language, code]) => (
43
+ <Tab2 key={language} id={language} label={language}>
44
+ <DocCode code={code} language={language} />
45
+ </Tab2>
46
+ ))}
47
+ </Tabs2>
48
+ )
@@ -66,7 +66,10 @@ describe('DocSDKs', () => {
66
66
  'it can render a %s method declaration',
67
67
  (sdkLanguage) => {
68
68
  store = createTestStore({
69
- settings: { initialized: false, sdkLanguage },
69
+ settings: {
70
+ initialized: false,
71
+ sdkLanguage: sdkLanguage,
72
+ },
70
73
  })
71
74
  renderWithReduxProvider(
72
75
  <DocSDKs api={api} method={api.methods.run_look} />,
@@ -93,6 +93,6 @@ describe('Header', () => {
93
93
  name: 'Compare Specifications',
94
94
  })
95
95
  .closest('a')
96
- ).toHaveAttribute('href', `/diff/${spec.key}/`)
96
+ ).toHaveAttribute('href', `/${spec.key}/diff`)
97
97
  })
98
98
  })
@@ -40,7 +40,7 @@ interface ApiSpecSelectorProps {
40
40
 
41
41
  export const ApiSpecSelector: FC<ApiSpecSelectorProps> = ({ spec }) => {
42
42
  const location = useLocation()
43
- const navigate = useNavigation()
43
+ const { navigate } = useNavigation()
44
44
  const specs = useSelector(selectSpecs)
45
45
  const options = Object.entries(specs).map(([key, spec]) => ({
46
46
  value: key,
@@ -24,61 +24,88 @@
24
24
 
25
25
  */
26
26
  import React from 'react'
27
- import { act, screen, waitFor } from '@testing-library/react'
27
+ import { screen, waitFor } from '@testing-library/react'
28
28
  import userEvent from '@testing-library/user-event'
29
29
  import { codeGenerators } from '@looker/sdk-codegen'
30
- import * as reactRedux from 'react-redux'
31
-
32
- import { registerTestEnvAdaptor } from '@looker/extension-utils'
33
- import { defaultSettingsState, settingsSlice } from '../../state'
34
- import { renderWithReduxProvider } from '../../test-utils'
30
+ import {
31
+ createTestStore,
32
+ renderWithRouterAndReduxProvider,
33
+ } from '../../test-utils'
34
+ import { findSdk } from '../../utils'
35
+ import { languages } from '../../test-data'
36
+ import { defaultSettingsState } from '../../state'
35
37
  import { SdkLanguageSelector } from './SdkLanguageSelector'
36
38
 
39
+ const mockHistoryPush = jest.fn()
40
+ jest.mock('react-router-dom', () => {
41
+ const ReactRouterDOM = jest.requireActual('react-router-dom')
42
+ return {
43
+ ...ReactRouterDOM,
44
+ useHistory: () => ({
45
+ push: mockHistoryPush,
46
+ location,
47
+ }),
48
+ }
49
+ })
37
50
  describe('SdkLanguageSelector', () => {
38
51
  window.HTMLElement.prototype.scrollIntoView = jest.fn()
52
+ const store = createTestStore({ settings: { initialized: true } })
39
53
 
40
54
  beforeEach(() => {
41
55
  localStorage.clear()
42
56
  })
43
57
 
44
- test('it has the correct default language selected', () => {
45
- renderWithReduxProvider(<SdkLanguageSelector />)
58
+ test('it has the correct default language selected', async () => {
59
+ renderWithRouterAndReduxProvider(<SdkLanguageSelector />, undefined, store)
46
60
  expect(screen.getByRole('textbox')).toHaveValue(
47
61
  defaultSettingsState.sdkLanguage
48
62
  )
49
63
  })
50
64
 
51
65
  test('it lists all available languages and "All" as options', async () => {
52
- renderWithReduxProvider(<SdkLanguageSelector />)
53
- await act(async () => {
54
- await userEvent.click(screen.getByRole('textbox'))
55
- await waitFor(() => {
56
- expect(screen.getAllByRole('option')).toHaveLength(
57
- codeGenerators.length + 1
58
- )
66
+ renderWithRouterAndReduxProvider(<SdkLanguageSelector />, undefined, store)
67
+ userEvent.click(screen.getByRole('textbox'))
68
+ await waitFor(() => {
69
+ expect(screen.getAllByRole('option')).toHaveLength(
70
+ codeGenerators.length + 1
71
+ )
72
+ languages.forEach((language) => {
73
+ expect(
74
+ screen.getByRole('option', { name: language })
75
+ ).toBeInTheDocument()
59
76
  })
60
77
  })
61
78
  })
62
79
 
63
- test('it stores the selected language in localStorage', async () => {
64
- registerTestEnvAdaptor()
65
- const mockDispatch = jest.fn()
66
- jest.spyOn(reactRedux, 'useDispatch').mockReturnValue(mockDispatch)
67
- renderWithReduxProvider(<SdkLanguageSelector />)
68
-
69
- const selector = screen.getByRole('textbox')
70
- expect(defaultSettingsState.sdkLanguage).toEqual('Python')
71
- expect(selector).toHaveValue('Python')
72
-
73
- userEvent.click(selector)
74
- await act(async () => {
75
- await userEvent.click(screen.getByRole('option', { name: 'TypeScript' }))
80
+ test.each(languages.filter((l) => l !== 'All'))(
81
+ 'choosing `%s` pushes its alias to url',
82
+ async (language) => {
83
+ renderWithRouterAndReduxProvider(
84
+ <SdkLanguageSelector />,
85
+ undefined,
86
+ store
87
+ )
88
+ const selector = screen.getByRole('textbox')
89
+ userEvent.click(selector)
76
90
  await waitFor(async () => {
77
- expect(mockDispatch).toHaveBeenLastCalledWith(
78
- settingsSlice.actions.setSdkLanguageAction({
79
- sdkLanguage: 'TypeScript',
80
- })
81
- )
91
+ await userEvent.click(screen.getByRole('option', { name: language }))
92
+ const sdk = findSdk(language)
93
+ expect(mockHistoryPush).toHaveBeenLastCalledWith({
94
+ pathname: location.pathname,
95
+ search: `sdk=${sdk.alias}`,
96
+ })
97
+ })
98
+ }
99
+ )
100
+
101
+ test("choosing 'All' removes sdk parameter from the url", async () => {
102
+ renderWithRouterAndReduxProvider(<SdkLanguageSelector />, undefined, store)
103
+ userEvent.click(screen.getByRole('textbox'))
104
+ await waitFor(async () => {
105
+ await userEvent.click(screen.getByRole('option', { name: 'All' }))
106
+ expect(mockHistoryPush).toHaveBeenLastCalledWith({
107
+ pathname: location.pathname,
108
+ search: '',
82
109
  })
83
110
  })
84
111
  })
@@ -24,43 +24,36 @@
24
24
 
25
25
  */
26
26
  import type { FC } from 'react'
27
- import React from 'react'
28
- import { codeGenerators } from '@looker/sdk-codegen'
27
+ import React, { useEffect, useState } from 'react'
29
28
  import { Select } from '@looker/components'
30
29
  import { useSelector } from 'react-redux'
31
- import type { SelectOptionProps } from '@looker/components'
32
-
33
- import { useSettingActions, selectSdkLanguage } from '../../state'
30
+ import { selectSdkLanguage } from '../../state'
31
+ import { allAlias, useNavigation } from '../../utils'
32
+ import { allSdkLanguageOptions } from './utils'
34
33
 
35
34
  /**
36
35
  * Allows the user to select their preferred SDK language
37
36
  */
38
37
  export const SdkLanguageSelector: FC = () => {
39
- const { setSdkLanguageAction } = useSettingActions()
38
+ const { navigate } = useNavigation()
40
39
  const selectedSdkLanguage = useSelector(selectSdkLanguage)
40
+ const [language, setLanguage] = useState(selectedSdkLanguage)
41
+ const options = allSdkLanguageOptions()
41
42
 
42
- const allSdkLanguages: SelectOptionProps[] = codeGenerators.map((gen) => ({
43
- value: gen.language,
44
- }))
45
-
46
- allSdkLanguages.push({
47
- options: [
48
- {
49
- value: 'All',
50
- },
51
- ],
52
- })
53
-
54
- const handleChange = (language: string) => {
55
- setSdkLanguageAction({ sdkLanguage: language })
43
+ const handleChange = (alias: string) => {
44
+ navigate(location.pathname, { sdk: alias === allAlias ? null : alias })
56
45
  }
57
46
 
47
+ useEffect(() => {
48
+ setLanguage(selectedSdkLanguage)
49
+ }, [selectedSdkLanguage])
50
+
58
51
  return (
59
52
  <Select
60
53
  aria-label="sdk language selector"
61
- value={selectedSdkLanguage}
54
+ value={language}
62
55
  onChange={handleChange}
63
- options={allSdkLanguages}
56
+ options={options}
64
57
  />
65
58
  )
66
59
  }
@@ -75,6 +75,6 @@ describe('SelectorContainer', () => {
75
75
  name: 'Compare Specifications',
76
76
  })
77
77
  .closest('a')
78
- ).toHaveAttribute('href', `/diff/${spec.key}/`)
78
+ ).toHaveAttribute('href', `/${spec.key}/diff`)
79
79
  })
80
80
  })
@@ -32,7 +32,7 @@ import { ChangeHistory } from '@styled-icons/material/ChangeHistory'
32
32
  import type { SpecItem } from '@looker/sdk-codegen'
33
33
 
34
34
  import { Link } from '../Link'
35
- import { diffPath } from '../../utils'
35
+ import { diffPath, useNavigation } from '../../utils'
36
36
  import { SdkLanguageSelector } from './SdkLanguageSelector'
37
37
  import { ApiSpecSelector } from './ApiSpecSelector'
38
38
 
@@ -49,17 +49,20 @@ export const HEADER_REM = 4
49
49
  export const SelectorContainer: FC<SelectorContainerProps> = ({
50
50
  spec,
51
51
  ...spaceProps
52
- }) => (
53
- <Space width="auto" {...spaceProps}>
54
- <SdkLanguageSelector />
55
- <ApiSpecSelector spec={spec} />
56
- <Link to={`/${diffPath}/${spec.key}/`}>
57
- <IconButton
58
- toggle
59
- label="Compare Specifications"
60
- icon={<ChangeHistory />}
61
- size="small"
62
- />
63
- </Link>
64
- </Space>
65
- )
52
+ }) => {
53
+ const { buildPathWithGlobalParams } = useNavigation()
54
+ return (
55
+ <Space width="auto" {...spaceProps}>
56
+ <SdkLanguageSelector />
57
+ <ApiSpecSelector spec={spec} />
58
+ <Link to={buildPathWithGlobalParams(`/${spec.key}/${diffPath}`)}>
59
+ <IconButton
60
+ toggle
61
+ label="Compare Specifications"
62
+ icon={<ChangeHistory />}
63
+ size="small"
64
+ />
65
+ </Link>
66
+ </Space>
67
+ )
68
+ }
@@ -23,31 +23,23 @@
23
23
  SOFTWARE.
24
24
 
25
25
  */
26
- import { useHistory } from 'react-router-dom'
26
+ import type { SelectOptionProps } from '@looker/components'
27
+ import { allSdkLanguages, allAlias } from '../../utils'
27
28
 
28
29
  /**
29
- * Hook for navigating to given route with specified query params
30
- *
31
- * @param path Pathname to navigate to
32
- * @param queryParams Hash of query param name/value pairs to include in the destination url
30
+ * @returns sdk language options for render
33
31
  */
34
-
35
- export const useNavigation = () => {
36
- const history = useHistory()
37
-
38
- const navigate = (path: string, queryParams?: { search?: string } | null) => {
39
- if (queryParams === undefined) {
40
- // if params passed in is undefined, maintain existing parameters in the URL
41
- const curParams = new URLSearchParams(history.location.search)
42
- history.push({ pathname: path, search: curParams.toString() })
43
- } else if (queryParams === null || Object.keys(queryParams).length === 0) {
44
- // if params passed in is null or empty, remove all parameters from the URL
45
- history.push({ pathname: path })
32
+ export const allSdkLanguageOptions = (): SelectOptionProps[] => {
33
+ const options = [] as SelectOptionProps[]
34
+ const languages = allSdkLanguages()
35
+ Object.entries(languages).forEach(([alias, language]) => {
36
+ const option = { value: alias, label: language }
37
+ if (alias === allAlias) {
38
+ options.push({ options: [option] })
46
39
  } else {
47
- // if we have new parameters passed in, push them to the URL
48
- history.push({ pathname: path, search: queryParams.search })
40
+ options.push(option)
49
41
  }
50
- }
42
+ })
51
43
 
52
- return navigate
44
+ return options
53
45
  }
@@ -34,6 +34,7 @@ import {
34
34
  TabPanels,
35
35
  useTabs,
36
36
  InputSearch,
37
+ Box2,
37
38
  } from '@looker/components'
38
39
  import type {
39
40
  SpecItem,
@@ -44,6 +45,7 @@ import type {
44
45
  } from '@looker/sdk-codegen'
45
46
  import { criteriaToSet, tagTypes } from '@looker/sdk-codegen'
46
47
  import { useSelector } from 'react-redux'
48
+ import { CopyLinkWrapper } from '@looker/run-it'
47
49
  import { useWindowSize, useNavigation } from '../../utils'
48
50
  import { HEADER_REM } from '../Header'
49
51
  import { selectSearchCriteria, selectSearchPattern } from '../../state'
@@ -68,7 +70,7 @@ interface SideNavProps {
68
70
 
69
71
  export const SideNav: FC<SideNavProps> = ({ headless = false, spec }) => {
70
72
  const location = useLocation()
71
- const navigate = useNavigation()
73
+ const { navigate, navigateWithGlobalParams } = useNavigation()
72
74
  const specKey = spec.key
73
75
  const tabNames = ['methods', 'types']
74
76
  const pathParts = location.pathname.split('/')
@@ -82,12 +84,12 @@ export const SideNav: FC<SideNavProps> = ({ headless = false, spec }) => {
82
84
  if (parts[1] === 'diff') {
83
85
  if (parts[3] !== tabNames[index]) {
84
86
  parts[3] = tabNames[index]
85
- navigate(parts.join('/'))
87
+ navigateWithGlobalParams(parts.join('/'))
86
88
  }
87
89
  } else {
88
90
  if (parts[2] !== tabNames[index]) {
89
91
  parts[2] = tabNames[index]
90
- navigate(parts.join('/'))
92
+ navigateWithGlobalParams(parts.join('/'))
91
93
  }
92
94
  }
93
95
  }
@@ -113,12 +115,14 @@ export const SideNav: FC<SideNavProps> = ({ headless = false, spec }) => {
113
115
  const searchParams = new URLSearchParams(location.search)
114
116
  if (debouncedPattern && debouncedPattern !== searchParams.get('s')) {
115
117
  searchParams.set('s', debouncedPattern)
116
- navigate(location.pathname, { search: searchParams.toString() })
118
+ navigate(location.pathname, { s: searchParams.get('s') })
117
119
  } else if (!debouncedPattern && searchParams.get('s')) {
118
120
  searchParams.delete('s')
119
- navigate(location.pathname, { search: searchParams.toString() })
121
+ navigate(location.pathname, { s: null })
120
122
  }
121
- }, [location.search, debouncedPattern])
123
+ }, [debouncedPattern])
124
+ // Removed location.search as dep to fix bug related to
125
+ // browser forward / backward navigation
122
126
 
123
127
  useEffect(() => {
124
128
  let results
@@ -126,6 +130,7 @@ export const SideNav: FC<SideNavProps> = ({ headless = false, spec }) => {
126
130
  let newTypes
127
131
  let newTypeTags
128
132
  const api = spec.api || ({} as ApiModel)
133
+ setSearchPattern(searchPattern)
129
134
 
130
135
  if (searchPattern && api.search) {
131
136
  results = api.search(searchPattern, criteriaToSet(searchCriteria))
@@ -160,18 +165,25 @@ export const SideNav: FC<SideNavProps> = ({ headless = false, spec }) => {
160
165
 
161
166
  return (
162
167
  <nav>
163
- <InputSearch
168
+ <Box2
164
169
  pl="large"
165
170
  pr="large"
166
171
  pb="large"
167
172
  pt={headless ? 'u3' : 'large'}
168
- aria-label="Search"
169
- onChange={handleInputChange}
170
- placeholder="Search"
171
- value={pattern}
172
- isClearable
173
- />
174
- <SearchMessage search={searchResults} />
173
+ position={'relative'}
174
+ width={'100%'}
175
+ >
176
+ <CopyLinkWrapper visible={!!pattern}>
177
+ <InputSearch
178
+ aria-label="Search"
179
+ onChange={handleInputChange}
180
+ placeholder="Search"
181
+ value={pattern}
182
+ isClearable
183
+ />
184
+ </CopyLinkWrapper>
185
+ <SearchMessage search={searchResults} />
186
+ </Box2>
175
187
  <TabList {...tabs} distribute>
176
188
  <Tab>Methods ({methodCount})</Tab>
177
189
  <Tab>Types ({typeCount})</Tab>
@@ -52,6 +52,10 @@ describe('SideNavMethods', () => {
52
52
  const methods = api.tags[tag]
53
53
  const specKey = '3.1'
54
54
 
55
+ beforeEach(() => {
56
+ jest.clearAllMocks()
57
+ })
58
+
55
59
  test('it renders provided methods', () => {
56
60
  renderWithRouterAndReduxProvider(
57
61
  <SideNavMethods methods={methods} tag={tag} specKey={specKey} />
@@ -72,10 +76,7 @@ describe('SideNavMethods', () => {
72
76
  const firstMethod = Object.values(methods)[0].schema.summary
73
77
  expect(screen.queryByText(firstMethod)).not.toBeInTheDocument()
74
78
  userEvent.click(screen.getByText(tag))
75
- expect(mockHistoryPush).toHaveBeenCalledWith({
76
- pathname: `/${specKey}/methods/${tag}`,
77
- search: '',
78
- })
79
+ expect(mockHistoryPush).toHaveBeenCalledWith(`/${specKey}/methods/${tag}`)
79
80
  expect(screen.getByRole('link', { name: firstMethod })).toBeInTheDocument()
80
81
  expect(screen.getAllByRole('link')).toHaveLength(
81
82
  Object.values(methods).length
@@ -97,10 +98,7 @@ describe('SideNavMethods', () => {
97
98
  Object.values(methods).length
98
99
  )
99
100
  userEvent.click(screen.getByText(tag))
100
- expect(mockHistoryPush).toHaveBeenCalledWith({
101
- pathname: `/${specKey}/methods`,
102
- search: '',
103
- })
101
+ expect(mockHistoryPush).toHaveBeenCalledWith(`/${specKey}/methods`)
104
102
  expect(screen.queryByText(firstMethod)).not.toBeInTheDocument()
105
103
  expect(screen.queryByRole('link')).not.toBeInTheDocument()
106
104
  })