@env-hopper/frontend-core 2.0.1-alpha

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 (385) hide show
  1. package/LICENSE +21 -0
  2. package/dist/apple-touch-180x180.png +0 -0
  3. package/dist/disable.well-known/appspecific/com.chrome.devtools.json +6 -0
  4. package/dist/env-hopper-16x16.png +0 -0
  5. package/dist/env-hopper-192x192.png +0 -0
  6. package/dist/env-hopper-32x32.png +0 -0
  7. package/dist/env-hopper-48x48.png +0 -0
  8. package/dist/env-hopper-512x512.png +0 -0
  9. package/dist/env-hopper-square.svg +114 -0
  10. package/dist/esm/App.d.ts +12 -0
  11. package/dist/esm/App.js +12 -0
  12. package/dist/esm/App.js.map +1 -0
  13. package/dist/esm/__tests__/modules/fuzzyMatchLogic/autoCompleteFilter.test.d.ts +1 -0
  14. package/dist/esm/__tests__/modules/fuzzyMatchLogic/features/prefixFracTokenMiddles.test.d.ts +1 -0
  15. package/dist/esm/__tests__/modules/fuzzyMatchLogic/fixLayout.test.d.ts +1 -0
  16. package/dist/esm/__tests__/modules/fuzzyMatchLogic/postFiltration.test.d.ts +1 -0
  17. package/dist/esm/__tests__/modules/fuzzyMatchLogic/testUtils.d.ts +2 -0
  18. package/dist/esm/__tests__/modules/fuzzyMatchLogic/tokenize.test.d.ts +1 -0
  19. package/dist/esm/__tests__/modules/resouceJump/findBestMatchByUrl.test.d.ts +1 -0
  20. package/dist/esm/__tests__/setupTests.d.ts +0 -0
  21. package/dist/esm/__tests__/util/availabilityMatrixUtils.test.d.ts +1 -0
  22. package/dist/esm/api/ApiQueryMagazine.d.ts +12 -0
  23. package/dist/esm/api/ApiQueryMagazine.js +16 -0
  24. package/dist/esm/api/ApiQueryMagazine.js.map +1 -0
  25. package/dist/esm/api/data/useQueryBootstrapConfig.d.ts +3 -0
  26. package/dist/esm/api/data/useQueryBootstrapConfig.js +14 -0
  27. package/dist/esm/api/data/useQueryBootstrapConfig.js.map +1 -0
  28. package/dist/esm/api/infra/createQueryClient.d.ts +7 -0
  29. package/dist/esm/api/infra/createQueryClient.js +23 -0
  30. package/dist/esm/api/infra/createQueryClient.js.map +1 -0
  31. package/dist/esm/api/infra/trpc.d.ts +93 -0
  32. package/dist/esm/api/infra/trpc.js +8 -0
  33. package/dist/esm/api/infra/trpc.js.map +1 -0
  34. package/dist/esm/api/unsorted/indexDataFetcher.d.ts +11 -0
  35. package/dist/esm/api/unsorted/indexDataFetcher.js +35 -0
  36. package/dist/esm/api/unsorted/indexDataFetcher.js.map +1 -0
  37. package/dist/esm/appPropsFactory.d.ts +2 -0
  38. package/dist/esm/appPropsFactory.js +32 -0
  39. package/dist/esm/appPropsFactory.js.map +1 -0
  40. package/dist/esm/assets/env-hopper-logo.svg.js +16 -0
  41. package/dist/esm/assets/env-hopper-logo.svg.js.map +1 -0
  42. package/dist/esm/components/ThemeSwitcher.d.ts +1 -0
  43. package/dist/esm/components/ThemeSwitcher.js +25 -0
  44. package/dist/esm/components/ThemeSwitcher.js.map +1 -0
  45. package/dist/esm/components/theme-provider.d.ts +2 -0
  46. package/dist/esm/components/theme-provider.js +10 -0
  47. package/dist/esm/components/theme-provider.js.map +1 -0
  48. package/dist/esm/components/ui/badge.d.ts +9 -0
  49. package/dist/esm/components/ui/breadcrumb.d.ts +46 -0
  50. package/dist/esm/components/ui/button.d.ts +16 -0
  51. package/dist/esm/components/ui/button.js +52 -0
  52. package/dist/esm/components/ui/button.js.map +1 -0
  53. package/dist/esm/components/ui/card.d.ts +38 -0
  54. package/dist/esm/components/ui/collapsible.d.ts +5 -0
  55. package/dist/esm/components/ui/dialog.d.ts +21 -0
  56. package/dist/esm/components/ui/dropdown-menu.d.ts +25 -0
  57. package/dist/esm/components/ui/input.d.ts +10 -0
  58. package/dist/esm/components/ui/popover.d.ts +7 -0
  59. package/dist/esm/components/ui/popover.js +14 -0
  60. package/dist/esm/components/ui/popover.js.map +1 -0
  61. package/dist/esm/components/ui/scroll-area.d.ts +5 -0
  62. package/dist/esm/components/ui/separator.d.ts +4 -0
  63. package/dist/esm/components/ui/separator.js +27 -0
  64. package/dist/esm/components/ui/separator.js.map +1 -0
  65. package/dist/esm/components/ui/tabs.d.ts +7 -0
  66. package/dist/esm/index.d.ts +3 -0
  67. package/dist/esm/index.js +7 -0
  68. package/dist/esm/index.js.map +1 -0
  69. package/dist/esm/lib/utils.d.ts +2 -0
  70. package/dist/esm/lib/utils.js +9 -0
  71. package/dist/esm/lib/utils.js.map +1 -0
  72. package/dist/esm/main.d.ts +0 -0
  73. package/dist/esm/modules/config/BootstrapConfigContext.d.ts +9 -0
  74. package/dist/esm/modules/config/BootstrapConfigContext.js +25 -0
  75. package/dist/esm/modules/config/BootstrapConfigContext.js.map +1 -0
  76. package/dist/esm/modules/config/GlobalConfigContext.d.ts +14 -0
  77. package/dist/esm/modules/config/GlobalConfigContext.js +21 -0
  78. package/dist/esm/modules/config/GlobalConfigContext.js.map +1 -0
  79. package/dist/esm/modules/environment/ApiQueryMagazineEnvironment.d.ts +12 -0
  80. package/dist/esm/modules/environment/ApiQueryMagazineEnvironment.js +13 -0
  81. package/dist/esm/modules/environment/ApiQueryMagazineEnvironment.js.map +1 -0
  82. package/dist/esm/modules/environment/EnvironmentContext.d.ts +15 -0
  83. package/dist/esm/modules/environment/EnvironmentContext.js +67 -0
  84. package/dist/esm/modules/environment/EnvironmentContext.js.map +1 -0
  85. package/dist/esm/modules/environment/types.d.ts +4 -0
  86. package/dist/esm/modules/environment/ui/EhEnvSelector.d.ts +9 -0
  87. package/dist/esm/modules/environment/ui/EhEnvSelector.js +167 -0
  88. package/dist/esm/modules/environment/ui/EhEnvSelector.js.map +1 -0
  89. package/dist/esm/modules/fuzzyMatchLogic/autoCompleteFilter.d.ts +3 -0
  90. package/dist/esm/modules/fuzzyMatchLogic/autoCompleteFilter.js +43 -0
  91. package/dist/esm/modules/fuzzyMatchLogic/autoCompleteFilter.js.map +1 -0
  92. package/dist/esm/modules/fuzzyMatchLogic/features/prefixFrac.d.ts +1 -0
  93. package/dist/esm/modules/fuzzyMatchLogic/features/prefixFrac.js +12 -0
  94. package/dist/esm/modules/fuzzyMatchLogic/features/prefixFrac.js.map +1 -0
  95. package/dist/esm/modules/fuzzyMatchLogic/features/prefixFracTokenMiddles.d.ts +2 -0
  96. package/dist/esm/modules/fuzzyMatchLogic/fixLayout.d.ts +2 -0
  97. package/dist/esm/modules/fuzzyMatchLogic/postFiltration.d.ts +2 -0
  98. package/dist/esm/modules/fuzzyMatchLogic/scoring.d.ts +2 -0
  99. package/dist/esm/modules/fuzzyMatchLogic/scoring.js +23 -0
  100. package/dist/esm/modules/fuzzyMatchLogic/scoring.js.map +1 -0
  101. package/dist/esm/modules/fuzzyMatchLogic/tokenize.d.ts +3 -0
  102. package/dist/esm/modules/fuzzyMatchLogic/types.d.ts +25 -0
  103. package/dist/esm/modules/fuzzyMatchLogic/utils.d.ts +2 -0
  104. package/dist/esm/modules/fuzzyMatchLogic/utils.js +12 -0
  105. package/dist/esm/modules/fuzzyMatchLogic/utils.js.map +1 -0
  106. package/dist/esm/modules/pluginCore/PluginManagerContext.d.ts +24 -0
  107. package/dist/esm/modules/pluginCore/PluginManagerContext.js +62 -0
  108. package/dist/esm/modules/pluginCore/PluginManagerContext.js.map +1 -0
  109. package/dist/esm/modules/pluginCore/makePluginManagerContext.d.ts +7 -0
  110. package/dist/esm/modules/pluginCore/makePluginManagerContext.js +27 -0
  111. package/dist/esm/modules/pluginCore/makePluginManagerContext.js.map +1 -0
  112. package/dist/esm/modules/pluginCore/types.d.ts +36 -0
  113. package/dist/esm/modules/pluginCore/types.js +7 -0
  114. package/dist/esm/modules/pluginCore/types.js.map +1 -0
  115. package/dist/esm/modules/resourceJump/ApiQueryMagazineResourceJump.d.ts +27 -0
  116. package/dist/esm/modules/resourceJump/ApiQueryMagazineResourceJump.js +26 -0
  117. package/dist/esm/modules/resourceJump/ApiQueryMagazineResourceJump.js.map +1 -0
  118. package/dist/esm/modules/resourceJump/ResourceJumpContext.d.ts +17 -0
  119. package/dist/esm/modules/resourceJump/ResourceJumpContext.js +88 -0
  120. package/dist/esm/modules/resourceJump/ResourceJumpContext.js.map +1 -0
  121. package/dist/esm/modules/resourceJump/buildJumpUrl.d.ts +2 -0
  122. package/dist/esm/modules/resourceJump/buildJumpUrl.js +32 -0
  123. package/dist/esm/modules/resourceJump/buildJumpUrl.js.map +1 -0
  124. package/dist/esm/modules/resourceJump/findBestMatchByUrl.d.ts +17 -0
  125. package/dist/esm/modules/resourceJump/findBestMatchByUrl.js +85 -0
  126. package/dist/esm/modules/resourceJump/findBestMatchByUrl.js.map +1 -0
  127. package/dist/esm/modules/resourceJump/helpers.d.ts +28 -0
  128. package/dist/esm/modules/resourceJump/helpers.js +19 -0
  129. package/dist/esm/modules/resourceJump/helpers.js.map +1 -0
  130. package/dist/esm/modules/resourceJump/routeLoader.d.ts +11 -0
  131. package/dist/esm/modules/resourceJump/routeLoader.js +43 -0
  132. package/dist/esm/modules/resourceJump/routeLoader.js.map +1 -0
  133. package/dist/esm/modules/resourceJump/types.d.ts +18 -0
  134. package/dist/esm/modules/resourceJump/ui/EhJumpResourceSelector.d.ts +20 -0
  135. package/dist/esm/modules/resourceJump/ui/EhJumpResourceSelector.js +209 -0
  136. package/dist/esm/modules/resourceJump/ui/EhJumpResourceSelector.js.map +1 -0
  137. package/dist/esm/modules/resourceJump/ui/JumpALink.d.ts +14 -0
  138. package/dist/esm/modules/resourceJump/ui/JumpALink.js +38 -0
  139. package/dist/esm/modules/resourceJump/ui/JumpALink.js.map +1 -0
  140. package/dist/esm/modules/resourceJump/ui/JumpMainButton.d.ts +5 -0
  141. package/dist/esm/modules/resourceJump/ui/JumpMainButton.js +66 -0
  142. package/dist/esm/modules/resourceJump/ui/JumpMainButton.js.map +1 -0
  143. package/dist/esm/modules/resourceJump/ui/ResouceJumpLayout.d.ts +5 -0
  144. package/dist/esm/modules/resourceJump/ui/ResouceJumpLayout.js +42 -0
  145. package/dist/esm/modules/resourceJump/ui/ResouceJumpLayout.js.map +1 -0
  146. package/dist/esm/plugins/builtin/pageUrl/PageUrlPluginContext.d.ts +9 -0
  147. package/dist/esm/plugins/builtin/pageUrl/PageUrlPluginContext.js +36 -0
  148. package/dist/esm/plugins/builtin/pageUrl/PageUrlPluginContext.js.map +1 -0
  149. package/dist/esm/plugins/builtin/pageUrl/pageUrlAutoCompletePlugin.d.ts +11 -0
  150. package/dist/esm/plugins/builtin/pageUrl/pageUrlAutoCompletePlugin.js +44 -0
  151. package/dist/esm/plugins/builtin/pageUrl/pageUrlAutoCompletePlugin.js.map +1 -0
  152. package/dist/esm/plugins/builtin/pageUrl/pageUrlJumpPlugin.d.ts +7 -0
  153. package/dist/esm/plugins/builtin/pageUrl/pageUrlJumpPlugin.js +29 -0
  154. package/dist/esm/plugins/builtin/pageUrl/pageUrlJumpPlugin.js.map +1 -0
  155. package/dist/esm/plugins/builtin/pageUrl/pageUrlTypes.d.ts +11 -0
  156. package/dist/esm/routeTree.gen.d.ts +142 -0
  157. package/dist/esm/routeTree.gen.js +77 -0
  158. package/dist/esm/routeTree.gen.js.map +1 -0
  159. package/dist/esm/routes/__root.d.ts +2 -0
  160. package/dist/esm/routes/__root.js +22 -0
  161. package/dist/esm/routes/__root.js.map +1 -0
  162. package/dist/esm/routes/_layout/app/$appSlug/sub/$subValue.d.ts +1 -0
  163. package/dist/esm/routes/_layout/app/$appSlug.d.ts +1 -0
  164. package/dist/esm/routes/_layout/app/_appSlug/sub/_subValue.js +18 -0
  165. package/dist/esm/routes/_layout/app/_appSlug/sub/_subValue.js.map +1 -0
  166. package/dist/esm/routes/_layout/app/_appSlug.js +18 -0
  167. package/dist/esm/routes/_layout/app/_appSlug.js.map +1 -0
  168. package/dist/esm/routes/_layout/env/$envSlug/app/$appSlug/sub/$subValue.d.ts +1 -0
  169. package/dist/esm/routes/_layout/env/$envSlug/app/$appSlug.d.ts +1 -0
  170. package/dist/esm/routes/_layout/env/$envSlug/sub/$subValue.d.ts +1 -0
  171. package/dist/esm/routes/_layout/env/$envSlug.d.ts +1 -0
  172. package/dist/esm/routes/_layout/env/_envSlug/app/_appSlug/sub/_subValue.js +20 -0
  173. package/dist/esm/routes/_layout/env/_envSlug/app/_appSlug/sub/_subValue.js.map +1 -0
  174. package/dist/esm/routes/_layout/env/_envSlug/app/_appSlug.js +18 -0
  175. package/dist/esm/routes/_layout/env/_envSlug/app/_appSlug.js.map +1 -0
  176. package/dist/esm/routes/_layout/env/_envSlug/sub/_subValue.js +18 -0
  177. package/dist/esm/routes/_layout/env/_envSlug/sub/_subValue.js.map +1 -0
  178. package/dist/esm/routes/_layout/env/_envSlug.js +18 -0
  179. package/dist/esm/routes/_layout/env/_envSlug.js.map +1 -0
  180. package/dist/esm/routes/_layout/index.d.ts +1 -0
  181. package/dist/esm/routes/_layout/index.js +18 -0
  182. package/dist/esm/routes/_layout/index.js.map +1 -0
  183. package/dist/esm/routes/_layout.d.ts +1 -0
  184. package/dist/esm/routes/_layout.js +12 -0
  185. package/dist/esm/routes/_layout.js.map +1 -0
  186. package/dist/esm/types/ehTypes.d.ts +31 -0
  187. package/dist/esm/types/slateTypes.d.ts +28 -0
  188. package/dist/esm/types/tanstackQuery.d.ts +11 -0
  189. package/dist/esm/types/types.d.ts +16 -0
  190. package/dist/esm/types/userBehaviourTypes.d.ts +76 -0
  191. package/dist/esm/types/utilityTypes.d.ts +1 -0
  192. package/dist/esm/ui/components/ActionCard.d.ts +9 -0
  193. package/dist/esm/ui/components/AppIcon.d.ts +7 -0
  194. package/dist/esm/ui/components/commandInput/EhBaseSelector.d.ts +6 -0
  195. package/dist/esm/ui/components/commandInput/EhBaseSelector.js +22 -0
  196. package/dist/esm/ui/components/commandInput/EhBaseSelector.js.map +1 -0
  197. package/dist/esm/ui/components/commandInput/types.d.ts +13 -0
  198. package/dist/esm/ui/components/contextDebug.d.ts +2 -0
  199. package/dist/esm/ui/components/contextDebug.js +12 -0
  200. package/dist/esm/ui/components/contextDebug.js.map +1 -0
  201. package/dist/esm/ui/components/controlPanel/BaseDropdownSelector.d.ts +11 -0
  202. package/dist/esm/ui/components/controlPanel/env/EnvDropdownContent.d.ts +5 -0
  203. package/dist/esm/ui/components/controlPanel/env/EnvDropdownSelector.d.ts +1 -0
  204. package/dist/esm/ui/components/error/DefaultErrorComponent.d.ts +2 -0
  205. package/dist/esm/ui/components/error/DefaultErrorComponent.js +13 -0
  206. package/dist/esm/ui/components/error/DefaultErrorComponent.js.map +1 -0
  207. package/dist/esm/ui/components/error/RooutErrorPage.d.ts +2 -0
  208. package/dist/esm/ui/components/error/RooutErrorPage.js +12 -0
  209. package/dist/esm/ui/components/error/RooutErrorPage.js.map +1 -0
  210. package/dist/esm/ui/components/footer/Footer.d.ts +1 -0
  211. package/dist/esm/ui/components/footer/Footer.js +38 -0
  212. package/dist/esm/ui/components/footer/Footer.js.map +1 -0
  213. package/dist/esm/ui/components/header/PlaygroundHeader.d.ts +1 -0
  214. package/dist/esm/ui/components/header/PlaygroundHeader.js +23 -0
  215. package/dist/esm/ui/components/header/PlaygroundHeader.js.map +1 -0
  216. package/dist/esm/ui/components/leftPanel/LeftPanel.d.ts +5 -0
  217. package/dist/esm/ui/components/quickBar/EnvQuickJumpBar.d.ts +5 -0
  218. package/dist/esm/ui/components/quickBar/EnvQuickJumpBar.js +52 -0
  219. package/dist/esm/ui/components/quickBar/EnvQuickJumpBar.js.map +1 -0
  220. package/dist/esm/ui/components/quickBar/QuickJumpBar.d.ts +5 -0
  221. package/dist/esm/ui/components/widgetPanel/AddWidgetCard.d.ts +5 -0
  222. package/dist/esm/ui/components/widgetPanel/WidgetGrid.d.ts +6 -0
  223. package/dist/esm/ui/components/widgets/CredentialsWidget.d.ts +11 -0
  224. package/dist/esm/ui/components/widgets/VersionWidget.d.ts +7 -0
  225. package/dist/esm/ui/error/NotFoundError.d.ts +1 -0
  226. package/dist/esm/ui/error/NotFoundError.js +16 -0
  227. package/dist/esm/ui/error/NotFoundError.js.map +1 -0
  228. package/dist/esm/ui/layout/Footer.d.ts +1 -0
  229. package/dist/esm/ui/layout/Header.d.ts +1 -0
  230. package/dist/esm/ui/layout/LoadingScreen.d.ts +4 -0
  231. package/dist/esm/ui/layout/LoadingScreen.js +14 -0
  232. package/dist/esm/ui/layout/LoadingScreen.js.map +1 -0
  233. package/dist/esm/ui/layout/MainLayout.d.ts +5 -0
  234. package/dist/esm/ui/layout/MainLayout.js +18 -0
  235. package/dist/esm/ui/layout/MainLayout.js.map +1 -0
  236. package/dist/esm/ui/layout/SideColumn.d.ts +1 -0
  237. package/dist/esm/ui/layout/TopLevelProviders.d.ts +5 -0
  238. package/dist/esm/ui/layout/TopLevelProviders.js +42 -0
  239. package/dist/esm/ui/layout/TopLevelProviders.js.map +1 -0
  240. package/dist/esm/ui/main/JumpTabContent.d.ts +1 -0
  241. package/dist/esm/ui/main/Tabs.d.ts +4 -0
  242. package/dist/esm/userDb/DbContext.d.ts +9 -0
  243. package/dist/esm/userDb/DbContext.js +18 -0
  244. package/dist/esm/userDb/DbContext.js.map +1 -0
  245. package/dist/esm/userDb/EhDb.d.ts +12 -0
  246. package/dist/esm/userDb/EhDb.js +20 -0
  247. package/dist/esm/userDb/EhDb.js.map +1 -0
  248. package/dist/esm/util/availabilityMatrixUtils.d.ts +12 -0
  249. package/dist/esm/util/availabilityMatrixUtils.js +57 -0
  250. package/dist/esm/util/availabilityMatrixUtils.js.map +1 -0
  251. package/dist/esm/util/createEhRouter.d.ts +7 -0
  252. package/dist/esm/util/createEhRouter.js +16 -0
  253. package/dist/esm/util/createEhRouter.js.map +1 -0
  254. package/dist/esm/util/highlightMatches.d.ts +2 -0
  255. package/dist/esm/util/highlightMatches.js +19 -0
  256. package/dist/esm/util/highlightMatches.js.map +1 -0
  257. package/dist/esm/util/reactQueryUtils.d.ts +6 -0
  258. package/dist/esm/util/reactQueryUtils.js +10 -0
  259. package/dist/esm/util/reactQueryUtils.js.map +1 -0
  260. package/dist/esm/util/route-utils.d.ts +6 -0
  261. package/dist/esm/util/route-utils.js +72 -0
  262. package/dist/esm/util/route-utils.js.map +1 -0
  263. package/dist/favicon.ico +0 -0
  264. package/dist/robots.txt +2 -0
  265. package/package.json +110 -0
  266. package/src/App.tsx +28 -0
  267. package/src/__tests__/modules/fuzzyMatchLogic/autoCompleteFilter.test.ts +185 -0
  268. package/src/__tests__/modules/fuzzyMatchLogic/features/prefixFracTokenMiddles.test.ts +23 -0
  269. package/src/__tests__/modules/fuzzyMatchLogic/fixLayout.test.ts +11 -0
  270. package/src/__tests__/modules/fuzzyMatchLogic/postFiltration.test.ts +15 -0
  271. package/src/__tests__/modules/fuzzyMatchLogic/testUtils.ts +8 -0
  272. package/src/__tests__/modules/fuzzyMatchLogic/tokenize.test.ts +65 -0
  273. package/src/__tests__/modules/resouceJump/findBestMatchByUrl.test.ts +234 -0
  274. package/src/__tests__/setupTests.tsx +0 -0
  275. package/src/__tests__/util/availabilityMatrixUtils.test.ts +61 -0
  276. package/src/api/ApiQueryMagazine.ts +15 -0
  277. package/src/api/data/useQueryBootstrapConfig.ts +17 -0
  278. package/src/api/infra/createQueryClient.ts +25 -0
  279. package/src/api/infra/trpc.ts +6 -0
  280. package/src/api/unsorted/indexDataFetcher.ts +46 -0
  281. package/src/appPropsFactory.ts +35 -0
  282. package/src/assets/env-hopper-logo.svg +114 -0
  283. package/src/components/ThemeSwitcher.tsx +22 -0
  284. package/src/components/theme-provider.tsx +8 -0
  285. package/src/components/ui/badge.tsx +37 -0
  286. package/src/components/ui/breadcrumb.tsx +128 -0
  287. package/src/components/ui/button.tsx +60 -0
  288. package/src/components/ui/card.tsx +95 -0
  289. package/src/components/ui/collapsible.tsx +31 -0
  290. package/src/components/ui/dialog.tsx +182 -0
  291. package/src/components/ui/dropdown-menu.tsx +257 -0
  292. package/src/components/ui/input.tsx +28 -0
  293. package/src/components/ui/popover.tsx +48 -0
  294. package/src/components/ui/scroll-area.tsx +58 -0
  295. package/src/components/ui/separator.tsx +26 -0
  296. package/src/components/ui/tabs.tsx +65 -0
  297. package/src/index.css +211 -0
  298. package/src/index.tsx +3 -0
  299. package/src/lib/utils.ts +7 -0
  300. package/src/main.tsx +53 -0
  301. package/src/modules/config/BootstrapConfigContext.tsx +33 -0
  302. package/src/modules/config/GlobalConfigContext.tsx +42 -0
  303. package/src/modules/environment/ApiQueryMagazineEnvironment.ts +12 -0
  304. package/src/modules/environment/EnvironmentContext.tsx +115 -0
  305. package/src/modules/environment/types.ts +4 -0
  306. package/src/modules/environment/ui/EhEnvSelector.tsx +191 -0
  307. package/src/modules/fuzzyMatchLogic/autoCompleteFilter.ts +186 -0
  308. package/src/modules/fuzzyMatchLogic/features/prefixFrac.ts +13 -0
  309. package/src/modules/fuzzyMatchLogic/features/prefixFracTokenMiddles.ts +29 -0
  310. package/src/modules/fuzzyMatchLogic/fixLayout.ts +24 -0
  311. package/src/modules/fuzzyMatchLogic/postFiltration.ts +35 -0
  312. package/src/modules/fuzzyMatchLogic/scoring.ts +42 -0
  313. package/src/modules/fuzzyMatchLogic/tokenize.ts +32 -0
  314. package/src/modules/fuzzyMatchLogic/types.ts +33 -0
  315. package/src/modules/fuzzyMatchLogic/utils.ts +18 -0
  316. package/src/modules/pluginCore/PluginManagerContext.tsx +107 -0
  317. package/src/modules/pluginCore/makePluginManagerContext.ts +35 -0
  318. package/src/modules/pluginCore/types.ts +54 -0
  319. package/src/modules/resourceJump/ApiQueryMagazineResourceJump.ts +31 -0
  320. package/src/modules/resourceJump/ResourceJumpContext.tsx +142 -0
  321. package/src/modules/resourceJump/buildJumpUrl.ts +40 -0
  322. package/src/modules/resourceJump/findBestMatchByUrl.ts +121 -0
  323. package/src/modules/resourceJump/helpers.ts +117 -0
  324. package/src/modules/resourceJump/routeLoader.ts +58 -0
  325. package/src/modules/resourceJump/types.ts +21 -0
  326. package/src/modules/resourceJump/ui/EhJumpResourceSelector.tsx +259 -0
  327. package/src/modules/resourceJump/ui/JumpALink.tsx +54 -0
  328. package/src/modules/resourceJump/ui/JumpMainButton.tsx +97 -0
  329. package/src/modules/resourceJump/ui/ResouceJumpLayout.tsx +73 -0
  330. package/src/plugins/builtin/pageUrl/PageUrlPluginContext.tsx +55 -0
  331. package/src/plugins/builtin/pageUrl/pageUrlAutoCompletePlugin.ts +66 -0
  332. package/src/plugins/builtin/pageUrl/pageUrlJumpPlugin.ts +36 -0
  333. package/src/plugins/builtin/pageUrl/pageUrlTypes.ts +17 -0
  334. package/src/routeTree.gen.ts +249 -0
  335. package/src/routes/__root.tsx +23 -0
  336. package/src/routes/_layout/app/$appSlug/sub/$subValue.tsx +15 -0
  337. package/src/routes/_layout/app/$appSlug.tsx +15 -0
  338. package/src/routes/_layout/env/$envSlug/app/$appSlug/sub/$subValue.tsx +17 -0
  339. package/src/routes/_layout/env/$envSlug/app/$appSlug.tsx +15 -0
  340. package/src/routes/_layout/env/$envSlug/sub/$subValue.tsx +15 -0
  341. package/src/routes/_layout/env/$envSlug.tsx +15 -0
  342. package/src/routes/_layout/index.tsx +16 -0
  343. package/src/routes/_layout.tsx +9 -0
  344. package/src/types/ehTypes.ts +40 -0
  345. package/src/types/slateTypes.ts +22 -0
  346. package/src/types/tanstackQuery.ts +14 -0
  347. package/src/types/types.ts +20 -0
  348. package/src/types/userBehaviourTypes.ts +100 -0
  349. package/src/types/utilityTypes.ts +1 -0
  350. package/src/types/vite-env.d.ts +1 -0
  351. package/src/ui/components/ActionCard.tsx +30 -0
  352. package/src/ui/components/AppIcon.tsx +48 -0
  353. package/src/ui/components/commandInput/EhBaseSelector.tsx +51 -0
  354. package/src/ui/components/commandInput/types.ts +22 -0
  355. package/src/ui/components/contextDebug.tsx +13 -0
  356. package/src/ui/components/controlPanel/BaseDropdownSelector.tsx +163 -0
  357. package/src/ui/components/controlPanel/env/EnvDropdownContent.tsx +114 -0
  358. package/src/ui/components/controlPanel/env/EnvDropdownSelector.tsx +21 -0
  359. package/src/ui/components/error/DefaultErrorComponent.tsx +38 -0
  360. package/src/ui/components/error/RooutErrorPage.tsx +10 -0
  361. package/src/ui/components/footer/Footer.tsx +32 -0
  362. package/src/ui/components/header/PlaygroundHeader.tsx +26 -0
  363. package/src/ui/components/leftPanel/LeftPanel.tsx +194 -0
  364. package/src/ui/components/quickBar/EnvQuickJumpBar.tsx +65 -0
  365. package/src/ui/components/quickBar/QuickJumpBar.tsx +101 -0
  366. package/src/ui/components/widgetPanel/AddWidgetCard.tsx +17 -0
  367. package/src/ui/components/widgetPanel/WidgetGrid.tsx +18 -0
  368. package/src/ui/components/widgets/CredentialsWidget.tsx +55 -0
  369. package/src/ui/components/widgets/VersionWidget.tsx +29 -0
  370. package/src/ui/error/NotFoundError.tsx +13 -0
  371. package/src/ui/layout/Footer.tsx +16 -0
  372. package/src/ui/layout/Header.tsx +14 -0
  373. package/src/ui/layout/LoadingScreen.tsx +17 -0
  374. package/src/ui/layout/MainLayout.tsx +27 -0
  375. package/src/ui/layout/SideColumn.tsx +3 -0
  376. package/src/ui/layout/TopLevelProviders.tsx +52 -0
  377. package/src/ui/main/JumpTabContent.tsx +12 -0
  378. package/src/ui/main/Tabs.tsx +29 -0
  379. package/src/userDb/DbContext.tsx +22 -0
  380. package/src/userDb/EhDb.ts +22 -0
  381. package/src/util/availabilityMatrixUtils.ts +80 -0
  382. package/src/util/createEhRouter.ts +20 -0
  383. package/src/util/highlightMatches.tsx +29 -0
  384. package/src/util/reactQueryUtils.ts +12 -0
  385. package/src/util/route-utils.ts +71 -0
package/src/index.css ADDED
@@ -0,0 +1,211 @@
1
+ /* @import url(./modules/resourceJump/ui/JumpMainButton.css); */
2
+ @import 'tailwindcss';
3
+
4
+ /* @import 'tw-animate-css'; */
5
+
6
+ @layer base {
7
+ :root {
8
+ --background: oklch(0.9842 0.0034 247.8575);
9
+ --foreground: oklch(0.2795 0.0368 260.031);
10
+ --card: oklch(1 0 0);
11
+ --card-foreground: oklch(0.2795 0.0368 260.031);
12
+ --popover: oklch(1 0 0);
13
+ --popover-foreground: oklch(0.2795 0.0368 260.031);
14
+ --primary: oklch(0.5854 0.2041 277.1173);
15
+ --primary-foreground: oklch(1 0 0);
16
+ --secondary: oklch(0.9276 0.0058 264.5313);
17
+ --secondary-foreground: oklch(0.3729 0.0306 259.7328);
18
+ --muted: oklch(0.967 0.0029 264.5419);
19
+ --muted-foreground: oklch(0.551 0.0234 264.3637);
20
+ --accent: oklch(0.9299 0.0334 272.7879);
21
+ --accent-foreground: oklch(0.3729 0.0306 259.7328);
22
+ --destructive: oklch(0.6368 0.2078 25.3313);
23
+ --destructive-foreground: oklch(1 0 0);
24
+ --border: oklch(0.8717 0.0093 258.3382);
25
+ --input: oklch(0.8717 0.0093 258.3382);
26
+ --ring: oklch(0.5854 0.2041 277.1173);
27
+ --chart-1: oklch(0.5854 0.2041 277.1173);
28
+ --chart-2: oklch(0.5106 0.2301 276.9656);
29
+ --chart-3: oklch(0.4568 0.2146 277.0229);
30
+ --chart-4: oklch(0.3984 0.1773 277.3662);
31
+ --chart-5: oklch(0.3588 0.1354 278.6973);
32
+ --sidebar: oklch(0.967 0.0029 264.5419);
33
+ --sidebar-foreground: oklch(0.2795 0.0368 260.031);
34
+ --sidebar-primary: oklch(0.5854 0.2041 277.1173);
35
+ --sidebar-primary-foreground: oklch(1 0 0);
36
+ --sidebar-accent: oklch(0.9299 0.0334 272.7879);
37
+ --sidebar-accent-foreground: oklch(0.3729 0.0306 259.7328);
38
+ --sidebar-border: oklch(0.8717 0.0093 258.3382);
39
+ --sidebar-ring: oklch(0.5854 0.2041 277.1173);
40
+ --font-sans:
41
+ ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji',
42
+ 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
43
+ --font-serif: Merriweather, serif;
44
+ --font-mono:
45
+ ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono',
46
+ 'Courier New', monospace;
47
+ --radius: 0.5rem;
48
+ --shadow-2xs: 0px 4px 8px -1px hsl(0 0% 0% / 0.05);
49
+ --shadow-xs: 0px 4px 8px -1px hsl(0 0% 0% / 0.05);
50
+ --shadow-sm:
51
+ 0px 4px 8px -1px hsl(0 0% 0% / 0.1), 0px 1px 2px -2px hsl(0 0% 0% / 0.1);
52
+ --shadow:
53
+ 0px 4px 8px -1px hsl(0 0% 0% / 0.1), 0px 1px 2px -2px hsl(0 0% 0% / 0.1);
54
+ --shadow-md:
55
+ 0px 4px 8px -1px hsl(0 0% 0% / 0.1), 0px 2px 4px -2px hsl(0 0% 0% / 0.1);
56
+ --shadow-lg:
57
+ 0px 4px 8px -1px hsl(0 0% 0% / 0.1), 0px 4px 6px -2px hsl(0 0% 0% / 0.1);
58
+ --shadow-xl:
59
+ 0px 4px 8px -1px hsl(0 0% 0% / 0.1), 0px 8px 10px -2px hsl(0 0% 0% / 0.1);
60
+ --shadow-2xl: 0px 4px 8px -1px hsl(0 0% 0% / 0.25);
61
+ --tracking-normal: 0em;
62
+ --spacing: 0.25rem;
63
+ --hopper: oklch(0.7488 0.149 130.38);
64
+ --animation-btn: 0.25s;
65
+ --btn-focus-scale: 0.95;
66
+ }
67
+
68
+ /* https://tweakcn.com/editor/theme */
69
+ .dark {
70
+ --background: hsl(212.29deg 18.32% 13.93%);
71
+ --foreground: oklch(0.9288 0.0126 255.5078);
72
+ --card: oklch(0.2795 0.0368 260.031);
73
+ --card-foreground: oklch(0.9288 0.0126 255.5078);
74
+ --popover: oklch(0.2795 0.0368 260.031);
75
+ --popover-foreground: oklch(0.9288 0.0126 255.5078);
76
+ --primary: oklch(0.6801 0.1583 276.9349);
77
+ --primary-foreground: oklch(0.2077 0.0398 265.7549);
78
+ --secondary: oklch(0.3351 0.0331 260.912);
79
+ --secondary-foreground: oklch(0.8717 0.0093 258.3382);
80
+ --muted: oklch(0.2795 0.0368 260.031);
81
+ --muted-foreground: oklch(0.7137 0.0192 261.3246);
82
+ --accent: oklch(0.3729 0.0306 259.7328);
83
+ --accent-foreground: oklch(0.8717 0.0093 258.3382);
84
+ --destructive: oklch(0.6368 0.2078 25.3313);
85
+ --destructive-foreground: oklch(0.2077 0.0398 265.7549);
86
+ --border: oklch(0.4461 0.0263 256.8018);
87
+ --input: oklch(0.4461 0.0263 256.8018);
88
+ --ring: oklch(0.6801 0.1583 276.9349);
89
+ --chart-1: oklch(0.6801 0.1583 276.9349);
90
+ --chart-2: oklch(0.5854 0.2041 277.1173);
91
+ --chart-3: oklch(0.5106 0.2301 276.9656);
92
+ --chart-4: oklch(0.4568 0.2146 277.0229);
93
+ --chart-5: oklch(0.3984 0.1773 277.3662);
94
+ --sidebar: oklch(0.2795 0.0368 260.031);
95
+ --sidebar-foreground: oklch(0.9288 0.0126 255.5078);
96
+ --sidebar-primary: oklch(0.6801 0.1583 276.9349);
97
+ --sidebar-primary-foreground: oklch(0.2077 0.0398 265.7549);
98
+ --sidebar-accent: oklch(0.3729 0.0306 259.7328);
99
+ --sidebar-accent-foreground: oklch(0.8717 0.0093 258.3382);
100
+ --sidebar-border: oklch(0.4461 0.0263 256.8018);
101
+ --sidebar-ring: oklch(0.6801 0.1583 276.9349);
102
+ --font-sans:
103
+ ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji',
104
+ 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
105
+ --font-serif: Merriweather, serif;
106
+ --font-mono:
107
+ ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono',
108
+ 'Courier New', monospace;
109
+ --radius: 0.5rem;
110
+ --shadow-2xs: 0px 4px 8px -1px hsl(0 0% 0% / 0.05);
111
+ --shadow-xs: 0px 4px 8px -1px hsl(0 0% 0% / 0.05);
112
+ --shadow-sm:
113
+ 0px 4px 8px -1px hsl(0 0% 0% / 0.1), 0px 1px 2px -2px hsl(0 0% 0% / 0.1);
114
+ --shadow:
115
+ 0px 4px 8px -1px hsl(0 0% 0% / 0.1), 0px 1px 2px -2px hsl(0 0% 0% / 0.1);
116
+ --shadow-md:
117
+ 0px 4px 8px -1px hsl(0 0% 0% / 0.1), 0px 2px 4px -2px hsl(0 0% 0% / 0.1);
118
+ --shadow-lg:
119
+ 0px 4px 8px -1px hsl(0 0% 0% / 0.1), 0px 4px 6px -2px hsl(0 0% 0% / 0.1);
120
+ --shadow-xl:
121
+ 0px 4px 8px -1px hsl(0 0% 0% / 0.1), 0px 8px 10px -2px hsl(0 0% 0% / 0.1);
122
+ --shadow-2xl: 0px 4px 8px -1px hsl(0 0% 0% / 0.25);
123
+
124
+ --highlight: var(--color-amber-900);
125
+ --hopper: oklch(0.7488 0.149 130.38);
126
+ --animation-btn: 0.25s;
127
+ --btn-focus-scale: 0.95;
128
+ }
129
+ }
130
+ @theme inline {
131
+ --color-background: var(--background);
132
+ --color-foreground: var(--foreground);
133
+ --color-card: var(--card);
134
+ --color-card-foreground: var(--card-foreground);
135
+ --color-popover: var(--popover);
136
+ --color-popover-foreground: var(--popover-foreground);
137
+ --color-primary: var(--primary);
138
+ --color-primary-foreground: var(--primary-foreground);
139
+ --color-secondary: var(--secondary);
140
+ --color-secondary-foreground: var(--secondary-foreground);
141
+ --color-muted: var(--muted);
142
+ --color-muted-foreground: var(--muted-foreground);
143
+ --color-accent: var(--accent);
144
+ --color-accent-foreground: var(--accent-foreground);
145
+ --color-destructive: var(--destructive);
146
+ --color-destructive-foreground: var(--destructive-foreground);
147
+ --color-border: var(--border);
148
+ --color-input: var(--input);
149
+ --color-ring: var(--ring);
150
+ --color-chart-1: var(--chart-1);
151
+ --color-chart-2: var(--chart-2);
152
+ --color-chart-3: var(--chart-3);
153
+ --color-chart-4: var(--chart-4);
154
+ --color-chart-5: var(--chart-5);
155
+ --color-sidebar: var(--sidebar);
156
+ --color-sidebar-foreground: var(--sidebar-foreground);
157
+ --color-sidebar-primary: var(--sidebar-primary);
158
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
159
+ --color-sidebar-accent: var(--sidebar-accent);
160
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
161
+ --color-sidebar-border: var(--sidebar-border);
162
+ --color-sidebar-ring: var(--sidebar-ring);
163
+
164
+ --font-sans: var(--font-sans);
165
+ --font-mono: var(--font-mono);
166
+ --font-serif: var(--font-serif);
167
+
168
+ --radius-sm: calc(var(--radius) - 4px);
169
+ --radius-md: calc(var(--radius) - 2px);
170
+ --radius-lg: var(--radius);
171
+ --radius-xl: calc(var(--radius) + 4px);
172
+
173
+ --shadow-2xs: var(--shadow-2xs);
174
+ --shadow-xs: var(--shadow-xs);
175
+ --shadow-sm: var(--shadow-sm);
176
+ --shadow: var(--shadow);
177
+ --shadow-md: var(--shadow-md);
178
+ --shadow-lg: var(--shadow-lg);
179
+ --shadow-xl: var(--shadow-xl);
180
+ --shadow-2xl: var(--shadow-2xl);
181
+
182
+ --color-highlight: var(--highlight);
183
+ --color-hopper: var(--hopper);
184
+
185
+ --animate-button-pop: button-pop var(--animation-btn, 0.25s) ease-out;
186
+ }
187
+
188
+ @layer base {
189
+ * {
190
+ @apply border-border outline-ring/50;
191
+ }
192
+ body {
193
+ @apply bg-background text-foreground;
194
+ }
195
+ }
196
+
197
+ @custom-variant dark (&:where(.dark, .dark *));
198
+
199
+ @keyframes button-pop {
200
+ 0% {
201
+ transform: scale(var(--btn-focus-scale, 0.98));
202
+ }
203
+
204
+ 40% {
205
+ transform: scale(1.02);
206
+ }
207
+
208
+ 100% {
209
+ transform: scale(1);
210
+ }
211
+ }
package/src/index.tsx ADDED
@@ -0,0 +1,3 @@
1
+ export { appPropsFactory } from './appPropsFactory.js'
2
+ export { App } from './App'
3
+ export type { AppProps } from './App'
@@ -0,0 +1,7 @@
1
+ import { clsx } from 'clsx'
2
+ import { twMerge } from 'tailwind-merge'
3
+ import type { ClassValue } from 'clsx'
4
+
5
+ export function cn(...inputs: Array<ClassValue>) {
6
+ return twMerge(clsx(inputs))
7
+ }
package/src/main.tsx ADDED
@@ -0,0 +1,53 @@
1
+ import { StrictMode } from 'react'
2
+ import ReactDOM from 'react-dom/client'
3
+ // import { registerSW } from 'virtual:pwa-register';
4
+ import './index.css'
5
+ import { createBrowserHistory } from '@tanstack/react-router'
6
+ import { createTRPCClient, httpBatchLink } from '@trpc/client'
7
+ import { EhDb as DbClass } from './userDb/EhDb'
8
+ import { PageUrlJumpPlugin } from './plugins/builtin/pageUrl/pageUrlJumpPlugin'
9
+ import type { TRPCRouter } from '@env-hopper/backend-core'
10
+ import type { EhPlugin } from './modules/pluginCore/types'
11
+ import { createEhRouter } from '~/util/createEhRouter'
12
+ import { createQueryClient } from '~/api/infra/createQueryClient'
13
+ import { App } from '~/App'
14
+
15
+ // registerSW();
16
+
17
+ const trpcClient = createTRPCClient<TRPCRouter>({
18
+ links: [
19
+ httpBatchLink({
20
+ url: 'http://localhost:4000/trpc',
21
+ }),
22
+ ],
23
+ })
24
+
25
+ const db = new DbClass()
26
+ const queryClient = createQueryClient({ trpcClient })
27
+ const plugins: Array<EhPlugin> = [new PageUrlJumpPlugin()]
28
+ const router = createEhRouter({
29
+ history: createBrowserHistory(),
30
+ context: {
31
+ queryClient,
32
+ trpcClient,
33
+ db,
34
+ plugins,
35
+ },
36
+ })
37
+
38
+ // Render the app
39
+
40
+ const rootElement = document.getElementById('root')!
41
+ if (!rootElement.innerHTML) {
42
+ const root = ReactDOM.createRoot(rootElement)
43
+ root.render(
44
+ <StrictMode>
45
+ <App
46
+ router={router}
47
+ queryClient={queryClient}
48
+ trpcClient={trpcClient}
49
+ db={db}
50
+ />
51
+ </StrictMode>,
52
+ )
53
+ }
@@ -0,0 +1,33 @@
1
+ import { createContext, use } from 'react'
2
+ import type { ReactNode } from 'react'
3
+ import type { BootstrapConfigData } from '@env-hopper/backend-core'
4
+
5
+ const BootstrapConfigContext = createContext<BootstrapConfigData | undefined>(
6
+ undefined,
7
+ )
8
+
9
+ interface BootstrapConfigProviderProps {
10
+ children: ReactNode
11
+ bootstrapConfig: BootstrapConfigData
12
+ }
13
+
14
+ export function BootstrapConfigProvider({
15
+ children,
16
+ bootstrapConfig,
17
+ }: BootstrapConfigProviderProps) {
18
+ return (
19
+ <BootstrapConfigContext value={bootstrapConfig}>
20
+ {children}
21
+ </BootstrapConfigContext>
22
+ )
23
+ }
24
+
25
+ export function useBootstrapConfig(): BootstrapConfigData {
26
+ const context = use(BootstrapConfigContext)
27
+ if (context === undefined) {
28
+ throw new Error(
29
+ 'useBootstrapConfig must be used within a BootstrapConfigProvider',
30
+ )
31
+ }
32
+ return context
33
+ }
@@ -0,0 +1,42 @@
1
+ import { createContext, use, useMemo } from 'react'
2
+ import type { ReactNode } from 'react'
3
+
4
+ interface FrontendConfig {
5
+ microinteractionsToKeep: number
6
+ searchHistoryToKeep: number
7
+ }
8
+
9
+ export interface GlobalConfigContext {
10
+ config: FrontendConfig
11
+ }
12
+
13
+ const GlobalConfigContext = createContext<GlobalConfigContext | undefined>(
14
+ undefined,
15
+ )
16
+
17
+ interface GlobalConfigProviderProps {
18
+ children: ReactNode
19
+ }
20
+
21
+ export function GlobalConfigProvider({ children }: GlobalConfigProviderProps) {
22
+ const value: GlobalConfigContext = useMemo(
23
+ () => ({
24
+ config: {
25
+ microinteractionsToKeep: 1000,
26
+ searchHistoryToKeep: 1000,
27
+ },
28
+ }),
29
+ [],
30
+ )
31
+ return <GlobalConfigContext value={value}>{children}</GlobalConfigContext>
32
+ }
33
+
34
+ export function useGlobalConfig(): GlobalConfigContext {
35
+ const context = use(GlobalConfigContext)
36
+ if (context === undefined) {
37
+ throw new Error(
38
+ 'useGlobalConfig must be used within a GlobalConfigProvider',
39
+ )
40
+ }
41
+ return context
42
+ }
@@ -0,0 +1,12 @@
1
+ import { queryOptions } from '@tanstack/react-query'
2
+ import type { DbAware } from '~/types/ehTypes'
3
+ import type { EnvironmentHistoryItem } from './types'
4
+
5
+ export class ApiQueryMagazineHistory {
6
+ static getEnvSelectionHistory({ db }: DbAware) {
7
+ return queryOptions<Array<EnvironmentHistoryItem>, Error>({
8
+ queryKey: ['envSelectionHistory'],
9
+ queryFn: () => db.environmentHistory.toArray(),
10
+ })
11
+ }
12
+ }
@@ -0,0 +1,115 @@
1
+ import {
2
+ createContext,
3
+ use,
4
+ useCallback,
5
+ useEffect,
6
+ useMemo,
7
+ useState,
8
+ } from 'react'
9
+ import { useBootstrapConfig } from '../config/BootstrapConfigContext'
10
+ import type { EhEnvIndexed } from '@env-hopper/backend-core'
11
+ import type { ReactNode } from 'react'
12
+ import type { EnvironmentHistoryItem } from './types'
13
+ import { useDb } from '~/userDb/DbContext'
14
+
15
+ export interface EnvironmentContext {
16
+ setCurrentEnv: (envSlug: string | undefined) => void
17
+ currentEnv: EhEnvIndexed | undefined
18
+ getHistory: () => Array<EnvironmentHistoryItem>
19
+ }
20
+
21
+ const EnvironmentContext = createContext<EnvironmentContext | undefined>(
22
+ undefined,
23
+ )
24
+
25
+ interface EnvironmentProviderProps {
26
+ children: ReactNode
27
+ initialEnvSlug?: string
28
+ }
29
+
30
+ export function EnvironmentProvider({
31
+ children,
32
+ initialEnvSlug,
33
+ }: EnvironmentProviderProps) {
34
+ const indexData = useBootstrapConfig()
35
+ const db = useDb()
36
+ const [history, setHistory] = useState<Array<EnvironmentHistoryItem>>([])
37
+
38
+ useEffect(() => {
39
+ const fetchHistory = async () => {
40
+ const historyItems = await db.environmentHistory
41
+ .toCollection()
42
+ .sortBy('timestamp')
43
+ setHistory(historyItems)
44
+ }
45
+ fetchHistory()
46
+ }, [db.environmentHistory])
47
+
48
+ const [currentEnvSlug, setCurrentEnvSlug] = useState<string | undefined>(
49
+ initialEnvSlug,
50
+ )
51
+
52
+ // Lookup functions
53
+ const findEnvBySlug = useCallback(
54
+ (envSlug: string | undefined): EhEnvIndexed | undefined => {
55
+ if (!envSlug) return undefined
56
+ return indexData.envs[envSlug]
57
+ },
58
+ [indexData.envs],
59
+ )
60
+
61
+ // Get current objects from slugs
62
+ const currentEnv = findEnvBySlug(currentEnvSlug)
63
+ const setCurrentEnv = useCallback(
64
+ (envSlug: string | undefined) => {
65
+ setCurrentEnvSlug(envSlug)
66
+ const timestamp = Date.now()
67
+ if (envSlug !== undefined) {
68
+ setHistory((prev) => [...prev, { envSlug, timestamp }])
69
+ db.environmentHistory.add({ envSlug, timestamp })
70
+ }
71
+ },
72
+ [db.environmentHistory],
73
+ )
74
+
75
+ const value: EnvironmentContext = useMemo(
76
+ () => ({
77
+ setCurrentEnv,
78
+ currentEnv,
79
+ getHistory: () => history,
80
+ }),
81
+ [currentEnv, setCurrentEnv, history],
82
+ )
83
+
84
+ // return (
85
+ // <EnvironmentContext value={value}></EnvironmentContext>
86
+ // recents: history,
87
+ // record: (envSlug: string) => {
88
+ // const timestamp = Date.now();
89
+ // setHistory((prev) => [...prev, { envSlug, timestamp }]);
90
+ // },
91
+ // },
92
+ // }), [currentEnv, setCurrentEnv, history]);
93
+
94
+ // return (
95
+ // <EnvironmentContext value={value}></EnvironmentContext>
96
+ // recents: [],
97
+ // record: (envSlug: string) => {
98
+ // const timestamp = Date.now();
99
+ // envHistory.recents.push({ envSlug, timestamp });
100
+ // },
101
+ // },
102
+ // }), [currentEnv, setCurrentEnv]);
103
+
104
+ return <EnvironmentContext value={value}>{children}</EnvironmentContext>
105
+ }
106
+
107
+ export function useEnvironmentContext(): EnvironmentContext {
108
+ const context = use(EnvironmentContext)
109
+ if (context === undefined) {
110
+ throw new Error(
111
+ 'useEnvironmentContext must be used within an EnvironmentProvider',
112
+ )
113
+ }
114
+ return context
115
+ }
@@ -0,0 +1,4 @@
1
+ export interface EnvironmentHistoryItem {
2
+ envSlug: string
3
+ timestamp: number
4
+ }
@@ -0,0 +1,191 @@
1
+ import { Popover, PopoverContent } from '@radix-ui/react-popover'
2
+ import { useCombobox } from 'downshift'
3
+ import { Edit3Icon, XIcon } from 'lucide-react'
4
+ import { listify, unique } from 'radashi'
5
+ import React, { useEffect, useMemo } from 'react'
6
+ import { EhBaseSelectorRoot } from '../../../ui/components/commandInput/EhBaseSelector'
7
+ import { PopoverTrigger } from '~/components/ui/popover'
8
+ import { useBootstrapConfig } from '~/modules/config/BootstrapConfigContext'
9
+ import { cn } from '~/lib/utils'
10
+ import { useEnvironmentContext } from '~/modules/environment/EnvironmentContext'
11
+ import {
12
+ fuzzySearch,
13
+ makeFuzzySearchIndex,
14
+ } from '~/modules/fuzzyMatchLogic/autoCompleteFilter'
15
+
16
+ interface EhEnvSelectorProps {
17
+ className?: string
18
+ }
19
+
20
+ export interface EhEnvSelectorItem {
21
+ slug: string
22
+ displayName: string
23
+ }
24
+
25
+ export function EhEnvSelector({ className = '' }: EhEnvSelectorProps) {
26
+ const { envs } = useBootstrapConfig()
27
+ const { currentEnv, setCurrentEnv } = useEnvironmentContext()
28
+
29
+ const allItems = useMemo(
30
+ () =>
31
+ listify(envs, (_, e) => {
32
+ return {
33
+ slug: e.slug,
34
+ displayName: e.displayName,
35
+ }
36
+ }),
37
+ [envs],
38
+ )
39
+
40
+ const searchIndex = useMemo(() => {
41
+ return makeFuzzySearchIndex({
42
+ entries: allItems,
43
+ })
44
+ }, [allItems])
45
+
46
+ const [displayedItems, setDisplayedItems] =
47
+ React.useState<Array<EhEnvSelectorItem>>(allItems)
48
+
49
+ const envFilter = (needle: string) => {
50
+ if (needle.trim() === '') {
51
+ return allItems
52
+ }
53
+ const newLocal = fuzzySearch(needle, {
54
+ index: searchIndex,
55
+ })
56
+ console.log(needle, newLocal)
57
+
58
+ return newLocal.map((e) => e.entry)
59
+ }
60
+
61
+ const {
62
+ isOpen: comboIsOpen,
63
+ getLabelProps,
64
+ getMenuProps,
65
+ getInputProps,
66
+ getToggleButtonProps,
67
+ highlightedIndex,
68
+ getItemProps,
69
+ selectItem,
70
+ inputValue: comboInputValue,
71
+ setInputValue,
72
+ } = useCombobox<EhEnvSelectorItem>({
73
+ onInputValueChange({
74
+ inputValue: changedInputValue,
75
+ isOpen: changedIsOpen,
76
+ }) {
77
+ if (changedIsOpen) {
78
+ const matchedIds = unique(envFilter(changedInputValue))
79
+ setDisplayedItems(matchedIds)
80
+ }
81
+ },
82
+ onSelectedItemChange({ selectedItem: changedSelectedItem }) {
83
+ setCurrentEnv(changedSelectedItem?.slug)
84
+ },
85
+ // selectedItem,
86
+ items: displayedItems,
87
+ itemToString(item) {
88
+ return (item && item.displayName) || ''
89
+ },
90
+ })
91
+
92
+ useEffect(() => {
93
+ if (currentEnv) {
94
+ const f = allItems.find((e) => e.slug === currentEnv.slug)
95
+ if (f) {
96
+ selectItem(f)
97
+ }
98
+ }
99
+ }, [allItems, currentEnv, selectItem])
100
+
101
+ return (
102
+ <EhBaseSelectorRoot className={className}>
103
+ <Popover open={comboIsOpen}>
104
+ <PopoverTrigger asChild>
105
+ <div className="relative group hover:cursor-pointer w-full">
106
+ <input
107
+ className={cn(
108
+ 'text-xl h-14 w-full rounded-md border border-input bg-background px-4 py-4 ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 ',
109
+ 'group-hover:border-secondary-foreground/60 group-hover:bg-secondary/30 focus:bg-secondary/30 focus:border-secondary-foreground/60',
110
+ 'pr-12 hover:cursor-pointer duration-300',
111
+ )}
112
+ {...getInputProps({
113
+ onMouseUp: (e) => {
114
+ const userHasSelectedSomeText =
115
+ e.currentTarget.selectionStart !==
116
+ e.currentTarget.selectionEnd
117
+ if (!userHasSelectedSomeText) {
118
+ // setInputValue('asdads')
119
+ e.currentTarget.select()
120
+ }
121
+ },
122
+ onKeyUp: (e) => {
123
+ if (e.key !== 'Enter') {
124
+ // console.log(e.target.value)
125
+ // setLastUsersInputText(e.target.value)
126
+ }
127
+ },
128
+ })}
129
+ />
130
+ {comboInputValue.length ? (
131
+ <XIcon
132
+ className="absolute right-5 top-1/2 -translate-y-1/2 stroke-secondary-foreground/50 group-hover:stroke-secondary-foreground/60 group-hover:rotate-3 group-hover:scale-95 hover:stroke-secondary-foreground hover:bg-secondary rounded-full"
133
+ onClick={() => setInputValue('')}
134
+ />
135
+ ) : (
136
+ <Edit3Icon
137
+ {...getToggleButtonProps()}
138
+ className="absolute right-5 top-1/2 -translate-y-1/2 stroke-secondary-foreground/50 group-hover:stroke-secondary-foreground/60 group-hover:rotate-3 group-hover:scale-95"
139
+ />
140
+ )}
141
+
142
+ <label
143
+ className={cn(
144
+ 'absolute text-sm text-secondary-foreground/50',
145
+ 'left-2 -top-0.5 -translate-y-1/2 text-muted-foreground bg-background rounded-2xl px-1',
146
+ )}
147
+ {...getLabelProps()}
148
+ >
149
+ Environment
150
+ </label>
151
+ </div>
152
+ </PopoverTrigger>
153
+
154
+ <PopoverContent
155
+ className={cn(
156
+ 'w-[var(--radix-popover-trigger-width)] max-h-[var(--radix-popover-content-available-height)] bg-popover text-popover-foreground z-50 origin-(--radix-popover-content-transform-origin) rounded-b-md border shadow-md outline-hidden',
157
+ { hidden: !comboIsOpen },
158
+ )}
159
+ onOpenAutoFocus={(e) => e.preventDefault()}
160
+ forceMount
161
+ >
162
+ <div {...getMenuProps()}>
163
+ {displayedItems.map((item, index) => (
164
+ <div
165
+ key={item.slug}
166
+ className={cn(
167
+ 'cursor-pointer text-secondary-foreground px-3 py-3 rounded-md',
168
+ {
169
+ // 'bg-secondary/40': comboSelectedItem?.slug === item.slug,
170
+ 'bg-primary/40': highlightedIndex === index,
171
+ },
172
+ )}
173
+ {...getItemProps({
174
+ item,
175
+ })}
176
+ >
177
+ {item.displayName}
178
+ </div>
179
+ ))}
180
+ {displayedItems.length === 0 && (
181
+ <div className="text-secondary-foreground/50">
182
+ '{comboInputValue}' not found. Try a different search.
183
+ </div>
184
+ )}
185
+ </div>
186
+ </PopoverContent>
187
+ {/* </PopoverAnchor> */}
188
+ </Popover>
189
+ </EhBaseSelectorRoot>
190
+ )
191
+ }