Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/ide/sync_router_and_store.js')
-rw-r--r--app/assets/javascripts/ide/sync_router_and_store.js55
1 files changed, 55 insertions, 0 deletions
diff --git a/app/assets/javascripts/ide/sync_router_and_store.js b/app/assets/javascripts/ide/sync_router_and_store.js
new file mode 100644
index 00000000000..1782c32b3b2
--- /dev/null
+++ b/app/assets/javascripts/ide/sync_router_and_store.js
@@ -0,0 +1,55 @@
+/* eslint-disable import/prefer-default-export */
+/**
+ * This method adds listeners to the given router and store and syncs their state with eachother
+ *
+ * ### Why?
+ *
+ * Previously the IDE had a circular dependency between a singleton router and a singleton store.
+ * This causes some integration testing headaches...
+ *
+ * At the time, the most effecient way to break this ciruclar dependency was to:
+ *
+ * - Replace the router with a factory function that receives a store reference
+ * - Have the store write to a certain state that can be watched by the router
+ *
+ * Hence... This helper function...
+ */
+export const syncRouterAndStore = (router, store) => {
+ const disposables = [];
+
+ let currentPath = '';
+
+ // sync store to router
+ disposables.push(
+ store.watch(
+ state => state.router.fullPath,
+ fullPath => {
+ if (currentPath === fullPath) {
+ return;
+ }
+
+ currentPath = fullPath;
+
+ router.push(fullPath);
+ },
+ ),
+ );
+
+ // sync router to store
+ disposables.push(
+ router.afterEach(to => {
+ if (currentPath === to.fullPath) {
+ return;
+ }
+
+ currentPath = to.fullPath;
+ store.dispatch('router/push', currentPath, { root: true });
+ }),
+ );
+
+ const unsync = () => {
+ disposables.forEach(fn => fn());
+ };
+
+ return unsync;
+};