walker.ts 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. // Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. import { type App, inject, ref } from 'vue'
  3. import type { RouteLocationRaw, Router } from 'vue-router'
  4. export class Walker {
  5. private previousRoute = ref<string | null>(null)
  6. static KEY_INJECT = Symbol('walker')
  7. constructor(private router: Router) {
  8. this.previousRoute.value = Walker.getHistoryBackRoute()
  9. router.afterEach(() => {
  10. this.previousRoute.value = Walker.getHistoryBackRoute()
  11. })
  12. }
  13. private static getHistoryBackRoute(): string | null {
  14. if (typeof window === 'undefined') return null
  15. const { state } = window.history
  16. if (state && typeof state.back === 'string') {
  17. return state.back
  18. }
  19. return null
  20. }
  21. public getBackUrl(backupRoute: RouteLocationRaw) {
  22. return this.previousRoute.value || backupRoute
  23. }
  24. public get hasBackUrl() {
  25. return this.previousRoute.value !== null
  26. }
  27. public async back(path: RouteLocationRaw, ignore: string[] = []) {
  28. const previous = this.previousRoute.value
  29. if (previous && !ignore.find((entry) => previous.includes(entry))) {
  30. return this.router.back()
  31. }
  32. return this.router.push(path)
  33. }
  34. }
  35. declare module '@vue/runtime-core' {
  36. export interface ComponentCustomProperties {
  37. $walker: Walker
  38. }
  39. }
  40. export const useWalker = (): Walker => {
  41. return inject(Walker.KEY_INJECT) as Walker
  42. }
  43. export const initializeWalker = (app: App, router: Router) => {
  44. const walker = new Walker(router)
  45. app.provide(Walker.KEY_INJECT, walker)
  46. app.config.globalProperties.$walker = walker
  47. }