mirror of
https://github.com/directus/directus.git
synced 2026-01-27 12:18:25 -05:00
Page tracking (#242)
* Add trackPage action to userStore * Track page in after each for router
This commit is contained in:
@@ -1,11 +1,18 @@
|
||||
import Vue from 'vue';
|
||||
import VueCompositionAPI from '@vue/composition-api';
|
||||
import { Route } from 'vue-router';
|
||||
import { onBeforeEach, onBeforeEnterProjectChooser, replaceRoutes, defaultRoutes } from './router';
|
||||
import {
|
||||
onBeforeEach,
|
||||
onAfterEach,
|
||||
onBeforeEnterProjectChooser,
|
||||
replaceRoutes,
|
||||
defaultRoutes
|
||||
} from './router';
|
||||
import api from '@/api';
|
||||
import * as auth from '@/auth';
|
||||
import { useProjectsStore } from '@/stores/projects';
|
||||
import { hydrate } from '@/hydrate';
|
||||
import useUserStore from '@/stores/user';
|
||||
|
||||
jest.mock('@/auth');
|
||||
jest.mock('@/hydrate');
|
||||
@@ -257,4 +264,46 @@ describe('Router', () => {
|
||||
expect(handler).toHaveBeenCalledWith(defaultRoutes);
|
||||
});
|
||||
});
|
||||
|
||||
describe('onAfterEach', () => {
|
||||
it('Calls the userStore trackPage method after some time', () => {
|
||||
jest.useFakeTimers();
|
||||
const userStore = useUserStore({});
|
||||
|
||||
jest.spyOn(userStore, 'trackPage');
|
||||
|
||||
const to = {
|
||||
fullPath: '/test',
|
||||
meta: {
|
||||
public: false
|
||||
}
|
||||
} as any;
|
||||
|
||||
onAfterEach(to);
|
||||
|
||||
jest.runAllTimers();
|
||||
|
||||
expect(userStore.trackPage).toHaveBeenCalledWith('/test');
|
||||
});
|
||||
|
||||
it('Does not track the page for public pages', () => {
|
||||
jest.useFakeTimers();
|
||||
const userStore = useUserStore({});
|
||||
|
||||
jest.spyOn(userStore, 'trackPage');
|
||||
|
||||
const to = {
|
||||
fullPath: '/test',
|
||||
meta: {
|
||||
public: true
|
||||
}
|
||||
} as any;
|
||||
|
||||
onAfterEach(to);
|
||||
|
||||
jest.runAllTimers();
|
||||
|
||||
expect(userStore.trackPage).not.toHaveBeenCalledWith('/test');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import VueRouter, { NavigationGuard, RouteConfig } from 'vue-router';
|
||||
import VueRouter, { NavigationGuard, RouteConfig, Route } from 'vue-router';
|
||||
import Debug from '@/routes/debug.vue';
|
||||
import { useProjectsStore } from '@/stores/projects';
|
||||
import LoginRoute from '@/routes/login';
|
||||
@@ -7,6 +7,7 @@ import ProjectChooserRoute from '@/routes/project-chooser';
|
||||
import { checkAuth } from '@/auth';
|
||||
import { hydrate, dehydrate } from '@/hydrate';
|
||||
import useAppStore from '@/stores/app';
|
||||
import useUserStore from '@/stores/user';
|
||||
|
||||
export const onBeforeEnterProjectChooser: NavigationGuard = (to, from, next) => {
|
||||
const projectsStore = useProjectsStore();
|
||||
@@ -133,7 +134,20 @@ export const onBeforeEach: NavigationGuard = async (to, from, next) => {
|
||||
return next();
|
||||
};
|
||||
|
||||
export const onAfterEach = (to: Route) => {
|
||||
const userStore = useUserStore();
|
||||
|
||||
if (to.meta.public !== true) {
|
||||
// The timeout gives the page some breathing room to load. No need to clog up the thread with
|
||||
// this call while more important things are loading
|
||||
setTimeout(() => {
|
||||
userStore.trackPage(to.fullPath);
|
||||
}, 2500);
|
||||
}
|
||||
};
|
||||
|
||||
router.beforeEach(onBeforeEach);
|
||||
router.afterEach(onAfterEach);
|
||||
|
||||
export default router;
|
||||
|
||||
|
||||
@@ -54,4 +54,40 @@ describe('Stores / User', () => {
|
||||
expect(userStore.reset).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Track Page', () => {
|
||||
it('Calls the right endpoint on tracking', async () => {
|
||||
const userStore = useUserStore(req);
|
||||
const projectsStore = useProjectsStore(req);
|
||||
|
||||
userStore.state.currentUser = {
|
||||
id: 5,
|
||||
last_page: 'test'
|
||||
} as any;
|
||||
|
||||
projectsStore.state.currentProjectKey = 'my-project';
|
||||
|
||||
await userStore.trackPage('/example');
|
||||
|
||||
expect(api.patch).toHaveBeenCalledWith('/my-project/users/me/tracking/page', {
|
||||
last_page: '/example'
|
||||
});
|
||||
});
|
||||
|
||||
it('Updates the store with the new last page', async () => {
|
||||
const userStore = useUserStore(req);
|
||||
const projectsStore = useProjectsStore(req);
|
||||
|
||||
userStore.state.currentUser = {
|
||||
id: 5,
|
||||
last_page: 'test'
|
||||
} as any;
|
||||
|
||||
projectsStore.state.currentProjectKey = 'my-project';
|
||||
|
||||
await userStore.trackPage('/example');
|
||||
|
||||
expect(userStore.state.currentUser!.last_page).toBe('/example');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -30,6 +30,18 @@ export const useUserStore = createStore({
|
||||
},
|
||||
async dehydrate() {
|
||||
this.reset();
|
||||
},
|
||||
async trackPage(page: string) {
|
||||
const projectsStore = useProjectsStore();
|
||||
const currentProjectKey = projectsStore.state.currentProjectKey;
|
||||
|
||||
await api.patch(`/${currentProjectKey}/users/me/tracking/page`, {
|
||||
last_page: page
|
||||
});
|
||||
|
||||
if (this.state.currentUser) {
|
||||
this.state.currentUser.last_page = page;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user