Vue 3 Nuxtism Removal (#10533)

* Removing everything related to scrollTrigger.

The latest vue router seems to behave exactly as it does with the modified scrollBehavior so it can all be removed.

* Removing unused $nuxt.{suffixes} that I found
- routeChanged  (didn't find any watches of this event)
- nbFetching (The only place reading this was a computed property which wasn't used anywhere)

* Replace the use of Vue[installKey]

* Removing some ssr rehydration code since we're not doing ssr

* Remove the remaining $nuxt.$on,$off,$emit and replace with the use of our primary store which already had related code

* Replacing usages of the .$nuxt on vue instances with globalApp references

* Removing SSR dead code

* Fixing an issue where extensions could still be referencing window.$nuxt. This now provides a deprecation warning.

* Migrating another $nuxt over to the window.$globalApp

* Removed the usage of Vue.config.$nux

* Removed the usage of Vue.util.defineReactive

- Saw that the Nuxt component wasn't needed any longer so I removed it instead of trying to work around Vue.util.defineReactive

* Re-run missing check

---------

Co-authored-by: cnotv <giuseppe.leo@suse.com>
This commit is contained in:
codyrancher 2024-03-11 11:38:25 -06:00 committed by GitHub
parent beddcb2866
commit b0d2dcbeb4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 101 additions and 469 deletions

View File

@ -47,11 +47,11 @@ export default {
const currentCluster = this.$store.getters['management/all'](MANAGEMENT.CLUSTER).find((x) => x.id === neu); const currentCluster = this.$store.getters['management/all'](MANAGEMENT.CLUSTER).find((x) => x.id === neu);
this.$nuxt.$loading.start(); window.$globalApp.$loading.start();
const kubeconfigContent = await currentCluster.generateKubeConfig(); const kubeconfigContent = await currentCluster.generateKubeConfig();
this.$nuxt.$loading.finish(); window.$globalApp.$loading.finish();
this.value.setData('kubeconfigContent', kubeconfigContent); this.value.setData('kubeconfigContent', kubeconfigContent);
}, },

View File

@ -20,8 +20,6 @@ import { getApplicableExtensionEnhancements } from '@shell/core/plugin-helpers';
import IconOrSvg from '@shell/components/IconOrSvg'; import IconOrSvg from '@shell/components/IconOrSvg';
import { wait } from '@shell/utils/async'; import { wait } from '@shell/utils/async';
const PAGE_HEADER_ACTION = 'page-action';
export default { export default {
components: { components: {
@ -117,7 +115,7 @@ export default {
}, },
showPageActions() { showPageActions() {
return !this.featureRancherDesktop && this.pageActions?.length; return !this.featureRancherDesktop && this.pageActions && this.pageActions.length;
}, },
showUserMenu() { showUserMenu() {
@ -274,7 +272,7 @@ export default {
}, },
pageAction(action) { pageAction(action) {
this.$nuxt.$emit(PAGE_HEADER_ACTION, action); this.$store.dispatch('handlePageAction', action);
}, },
checkClusterName() { checkClusterName() {

View File

@ -30,13 +30,8 @@ export default {
const listeners = {} const listeners = {}
// Add triggerScroll event on beforeEnter (fix #1376)
const beforeEnter = listeners.beforeEnter const beforeEnter = listeners.beforeEnter
listeners.beforeEnter = (el) => { listeners.beforeEnter = (el) => {
// Ensure to trigger scroll event after calling scrollBehavior
window.$nuxt.$nextTick(() => {
window.$nuxt.$emit('triggerScroll')
})
if (beforeEnter) { if (beforeEnter) {
return beforeEnter.call(_parent, el) return beforeEnter.call(_parent, el)
} }

View File

@ -68,7 +68,7 @@ export default {
}, },
canPrefetch () { canPrefetch () {
const conn = navigator.connection const conn = navigator.connection
const hasBadConnection = this.$nuxt.isOffline || (conn && ((conn.effectiveType || '').includes('2g') || conn.saveData)) const hasBadConnection = window.$globalApp.isOffline || (conn && ((conn.effectiveType || '').includes('2g') || conn.saveData))
return !hasBadConnection return !hasBadConnection
}, },

View File

@ -1,101 +0,0 @@
import Vue from 'vue'
import { compile } from '../../utils/nuxt'
import NuxtError from '../../components/templates/error.vue'
import NuxtChild from './nuxt-child'
export default {
name: 'Nuxt',
components: {
NuxtChild,
NuxtError
},
props: {
nuxtChildKey: {
type: String,
default: undefined
},
keepAlive: Boolean,
keepAliveProps: {
type: Object,
default: undefined
},
name: {
type: String,
default: 'default'
}
},
errorCaptured (error) {
// if we receive and error while showing the NuxtError component
// capture the error and force an immediate update so we re-render
// without the NuxtError component
if (this.displayingNuxtError) {
this.errorFromNuxtError = error
this.$forceUpdate()
}
},
computed: {
routerViewKey () {
// If nuxtChildKey prop is given or current route has children
if (typeof this.nuxtChildKey !== 'undefined' || this.$route.matched.length > 1) {
return this.nuxtChildKey || compile(this.$route.matched[0].path)(this.$route.params)
}
const [matchedRoute] = this.$route.matched
if (!matchedRoute) {
return this.$route.path
}
const Component = matchedRoute.components.default
if (Component && Component.options) {
const { options } = Component
if (options.key) {
return (typeof options.key === 'function' ? options.key(this.$route) : options.key)
}
}
const strict = /\/$/.test(matchedRoute.path)
return strict ? this.$route.path : this.$route.path.replace(/\/$/, '')
}
},
beforeCreate () {
Vue.util.defineReactive(this, 'nuxt', this.$root.$options.nuxt)
},
render (h) {
// if there is no error
if (!this.nuxt.err) {
// Directly return nuxt child
return h('NuxtChild', {
key: this.routerViewKey,
props: this.$props
})
}
// if an error occurred within NuxtError show a simple
// error message instead to prevent looping
if (this.errorFromNuxtError) {
this.$nextTick(() => (this.errorFromNuxtError = false))
return h('div', {}, [
h('h2', 'An error occurred while showing the error page'),
h('p', 'Unfortunately an error occurred and while showing the error page another error occurred'),
h('p', `Error details: ${this.errorFromNuxtError.toString()}`),
h('nuxt-link', { props: { to: '/' } }, 'Go back to home')
])
}
// track if we are showing the NuxtError component
this.displayingNuxtError = true
this.$nextTick(() => (this.displayingNuxtError = false))
return h(NuxtError, {
props: {
error: this.nuxt.err
}
})
}
}

View File

@ -12,7 +12,7 @@ export default {
computed: { computed: {
error() { error() {
return window.$nuxt.nuxt.err || {}; return window.$globalApp.nuxt.err || {};
}, },
statusCode() { statusCode() {
return (this.error && this.error.statusCode) || 599; return (this.error && this.error.statusCode) || 599;

View File

@ -2,7 +2,6 @@ import Vue from 'vue';
import Router from 'vue-router'; import Router from 'vue-router';
import { normalizeURL } from 'ufo'; import { normalizeURL } from 'ufo';
import { interopDefault } from '../utils/nuxt'; import { interopDefault } from '../utils/nuxt';
import scrollBehavior from '../utils/router.scrollBehavior.js';
const emptyFn = () => {}; const emptyFn = () => {};
@ -12,7 +11,6 @@ export const routerOptions = {
mode: 'history', mode: 'history',
// Note: router base comes from the ROUTER_BASE env var // Note: router base comes from the ROUTER_BASE env var
base: process.env.routerBase || '/', base: process.env.routerBase || '/',
scrollBehavior,
routes: [ routes: [
{ {

View File

@ -66,7 +66,7 @@ let store = {};
// Update `root.modules` with the latest definitions. // Update `root.modules` with the latest definitions.
updateModules(); updateModules();
// Trigger a hot update in the store. // Trigger a hot update in the store.
window.$nuxt.$store.hotUpdate(store); window.$globalApp.$store.hotUpdate(store);
}); });
} }
})(); })();

View File

@ -30,19 +30,18 @@ export default {
isOnline: true, isOnline: true,
showErrorPage: false, showErrorPage: false,
nbFetching: 0
}), }),
beforeCreate() {
Vue.util.defineReactive(this, 'nuxt', this.$options.nuxt);
},
created() { created() {
// Add this.$nuxt in child instances
this.$root.$options.$nuxt = this;
// add to window so we can listen when ready // add to window so we can listen when ready
window.$nuxt = this; window.$globalApp = this;
Object.defineProperty(window, '$nuxt', {
get() {
console.warn('window.$nuxt is deprecated. It would be best to stop using globalState all together. For an alternative you can use window.$globalApp.'); // eslint-disable-line no-console
return window.$globalApp;
}
});
this.refreshOnlineStatus(); this.refreshOnlineStatus();
// Setup the listeners // Setup the listeners
@ -50,7 +49,7 @@ export default {
window.addEventListener('offline', this.refreshOnlineStatus); window.addEventListener('offline', this.refreshOnlineStatus);
// Add $nuxt.error() // Add $nuxt.error()
this.error = this.nuxt.error; this.error = this.$options.nuxt.error;
// Add $nuxt.context // Add $nuxt.context
this.context = this.$options.context; this.context = this.$options.context;
}, },
@ -65,10 +64,6 @@ export default {
isOffline() { isOffline() {
return !this.isOnline; return !this.isOnline;
}, },
isFetching() {
return this.nbFetching > 0;
},
}, },
methods: { methods: {
@ -131,10 +126,10 @@ export default {
this.$loading.finish(); this.$loading.finish();
}, },
errorChanged() { errorChanged() {
if (this.nuxt.err) { if (this.$options.nuxt.err) {
if (this.$loading) { if (this.$loading) {
if (this.$loading.fail) { if (this.$loading.fail) {
this.$loading.fail(this.nuxt.err); this.$loading.fail(this.$options.nuxt.err);
} }
if (this.$loading.finish) { if (this.$loading.finish) {
this.$loading.finish(); this.$loading.finish();

View File

@ -30,10 +30,7 @@ const isDev = process.env.dev;
const debug = isDev; const debug = isDev;
// Fetch mixin // Fetch mixin
if (!Vue.__nuxt__fetch__mixin__) { Vue.mixin(fetchMixin);
Vue.mixin(fetchMixin);
Vue.__nuxt__fetch__mixin__ = true;
}
// Component: <NuxtLink> // Component: <NuxtLink>
Vue.component(NuxtLink.name, NuxtLink); Vue.component(NuxtLink.name, NuxtLink);
@ -48,8 +45,7 @@ let _lastPaths = [];
let app; let app;
let router; let router;
// Try to rehydrate SSR data from window const NUXT = {};
const NUXT = window.__NUXT__ || {};
const $config = nuxt.publicRuntimeConfig || {}; // eslint-disable-line no-undef const $config = nuxt.publicRuntimeConfig || {}; // eslint-disable-line no-undef
@ -60,58 +56,42 @@ if ($config._app) {
Object.assign(Vue.config, { silent: false, performance: true }); Object.assign(Vue.config, { silent: false, performance: true });
if (debug) { if (debug) {
const logs = NUXT.logs || []; const defaultErrorHandler = Vue.config.errorHandler;
if (logs.length > 0) { Vue.config.errorHandler = async(err, vm, info, ...rest) => {
const ssrLogStyle = 'background: #2E495E;border-radius: 0.5em;color: white;font-weight: bold;padding: 2px 0.5em;';
console.group && console.group('%cNuxt SSR', ssrLogStyle); // eslint-disable-line no-console
logs.forEach((logObj) => (console[logObj.type] || console.log)(...logObj.args)); // eslint-disable-line no-console
delete NUXT.logs;
console.groupEnd && console.groupEnd(); // eslint-disable-line no-console
}
// Setup global Vue error handler
if (!Vue.config.$nuxt) {
const defaultErrorHandler = Vue.config.errorHandler;
Vue.config.errorHandler = async(err, vm, info, ...rest) => {
// Call other handler if exist // Call other handler if exist
let handled = null; let handled = null;
if (typeof defaultErrorHandler === 'function') { if (typeof defaultErrorHandler === 'function') {
handled = defaultErrorHandler(err, vm, info, ...rest); handled = defaultErrorHandler(err, vm, info, ...rest);
} }
if (handled === true) { if (handled === true) {
return handled; return handled;
}
if (vm && vm.$root) {
const nuxtApp = Object.keys(window.$globalApp)
.find((nuxtInstance) => vm.$root[nuxtInstance]);
// Show Nuxt Error Page
if (nuxtApp && vm.$root[nuxtApp].error && info !== 'render function') {
const currentApp = vm.$root[nuxtApp];
currentApp.error(err);
} }
}
if (vm && vm.$root) { if (typeof defaultErrorHandler === 'function') {
const nuxtApp = Object.keys(Vue.config.$nuxt) return handled;
.find((nuxtInstance) => vm.$root[nuxtInstance]); }
// Show Nuxt Error Page // Log to console
if (nuxtApp && vm.$root[nuxtApp].error && info !== 'render function') { if (process.env.NODE_ENV !== 'production') {
const currentApp = vm.$root[nuxtApp]; console.error(err); // eslint-disable-line no-console
} else {
currentApp.error(err); console.error(err.message || err); // eslint-disable-line no-console
} }
} };
if (typeof defaultErrorHandler === 'function') {
return handled;
}
// Log to console
if (process.env.NODE_ENV !== 'production') {
console.error(err); // eslint-disable-line no-console
} else {
console.error(err.message || err); // eslint-disable-line no-console
}
};
Vue.config.$nuxt = {};
}
Vue.config.$nuxt.$nuxt = true;
} }
const errorHandler = Vue.config.errorHandler || console.error; // eslint-disable-line no-console const errorHandler = Vue.config.errorHandler || console.error; // eslint-disable-line no-console
@ -173,7 +153,6 @@ async function loadAsyncComponents(to, from, next) {
} }
this.error({ statusCode, message }); this.error({ statusCode, message });
this.$nuxt.$emit('routeChanged', to, from, err);
next(); next();
} }
} }
@ -444,15 +423,11 @@ async function render(to, from, next) {
} catch (err) { } catch (err) {
const error = err || {}; const error = err || {};
if (error.message === 'ERR_REDIRECT') {
return this.$nuxt.$emit('routeChanged', to, from, error);
}
_lastPaths = []; _lastPaths = [];
globalHandleError(error); globalHandleError(error);
this.error(error); this.error(error);
this.$nuxt.$emit('routeChanged', to, from, error);
next(); next();
} }
} }
@ -488,8 +463,6 @@ function fixPrepatch(to, ___) {
const instances = getMatchedComponentsInstances(to); const instances = getMatchedComponentsInstances(to);
const Components = getMatchedComponents(to); const Components = getMatchedComponents(to);
let triggerScroll = false;
Vue.nextTick(() => { Vue.nextTick(() => {
instances.forEach((instance, i) => { instances.forEach((instance, i) => {
if (!instance || instance._isDestroyed) { if (!instance || instance._isDestroyed) {
@ -507,18 +480,9 @@ function fixPrepatch(to, ___) {
for (const key in newData) { for (const key in newData) {
Vue.set(instance.$data, key, newData[key]); Vue.set(instance.$data, key, newData[key]);
} }
triggerScroll = true;
} }
}); });
if (triggerScroll) {
// Ensure to trigger scroll event after calling scrollBehavior
window.$nuxt.$nextTick(() => {
window.$nuxt.$emit('triggerScroll');
});
}
checkForErrors(this); checkForErrors(this);
// Hot reloading // Hot reloading
@ -538,11 +502,6 @@ function nuxtReady(_app) {
if (typeof window._onNuxtLoaded === 'function') { if (typeof window._onNuxtLoaded === 'function') {
window._onNuxtLoaded(_app); window._onNuxtLoaded(_app);
} }
// Add router hooks
router.afterEach((to, from) => {
// Wait for fixPrepatch + $data updates
Vue.nextTick(() => _app.$nuxt.$emit('routeChanged', to, from));
});
} }
const noopData = () => { const noopData = () => {
@ -569,7 +528,7 @@ function hotReloadAPI(_app) {
return; return;
} }
const $components = getNuxtChildComponents(_app.$nuxt, []); const $components = getNuxtChildComponents(window.$globalApp, []);
$components.forEach(addHotReload.bind(_app)); $components.forEach(addHotReload.bind(_app));
} }

View File

@ -4,7 +4,6 @@
import Vue from 'vue'; import Vue from 'vue';
import { createRouter } from '../config/router.js'; import { createRouter } from '../config/router.js';
import NuxtChild from '../components/nuxt/nuxt-child.js'; import NuxtChild from '../components/nuxt/nuxt-child.js';
import Nuxt from '../components/nuxt/nuxt.js';
import App from './App.js'; import App from './App.js';
import { setContext, getLocation, getRouteData, normalizeError } from '../utils/nuxt'; import { setContext, getLocation, getRouteData, normalizeError } from '../utils/nuxt';
import { createStore } from '../config/store.js'; import { createStore } from '../config/store.js';
@ -68,24 +67,6 @@ loadDirectives();
Vue.component(NuxtChild.name, NuxtChild); Vue.component(NuxtChild.name, NuxtChild);
Vue.component('NChild', NuxtChild); Vue.component('NChild', NuxtChild);
// Component NuxtLink is imported in server.js or client.js
// Component: <Nuxt>
Vue.component(Nuxt.name, Nuxt);
Object.defineProperty(Vue.prototype, '$nuxt', {
get() {
const globalNuxt = this.$root.$options.$nuxt;
if (!globalNuxt && typeof window !== 'undefined') {
return window.$nuxt;
}
return globalNuxt;
},
configurable: true
});
async function createApp(config = {}) { async function createApp(config = {}) {
const router = await createRouter(config); const router = await createRouter(config);
@ -164,10 +145,12 @@ async function createApp(config = {}) {
// Check if plugin not already installed // Check if plugin not already installed
const installKey = `__nuxt_${ key }_installed__`; const installKey = `__nuxt_${ key }_installed__`;
if (Vue[installKey]) { window.installedPlugins = window.installedPlugins || {};
if (window.installedPlugins[installKey]) {
return; return;
} }
Vue[installKey] = true; window[window.installedPlugins] = true;
// Call Vue.use() to install the plugin into vm // Call Vue.use() to install the plugin into vm
Vue.use(() => { Vue.use(() => {
if (!Object.prototype.hasOwnProperty.call(Vue.prototype, key)) { if (!Object.prototype.hasOwnProperty.call(Vue.prototype, key)) {
@ -183,11 +166,6 @@ async function createApp(config = {}) {
// Inject runtime config as $config // Inject runtime config as $config
inject('config', config); inject('config', config);
// Replace store state before plugins execution
if (window.__NUXT__ && window.__NUXT__.state) {
store.replaceState(window.__NUXT__.state);
}
// Plugin execution // Plugin execution
if (typeof cookieUniversalNuxt === 'function') { if (typeof cookieUniversalNuxt === 'function') {
await cookieUniversalNuxt(app.context, inject); await cookieUniversalNuxt(app.context, inject);

View File

@ -1,9 +1,5 @@
import Vue from 'vue';
import { hasFetch, normalizeError, addLifecycleHook } from '../utils/nuxt'; import { hasFetch, normalizeError, addLifecycleHook } from '../utils/nuxt';
const isSsrHydration = (vm) => vm.$vnode && vm.$vnode.elm && vm.$vnode.elm.dataset && vm.$vnode.elm.dataset.fetchKey;
const nuxtState = window.__NUXT__;
export default { export default {
beforeCreate() { beforeCreate() {
if (!hasFetch(this)) { if (!hasFetch(this)) {
@ -12,15 +8,24 @@ export default {
this._fetchDelay = typeof this.$options.fetchDelay === 'number' ? this.$options.fetchDelay : 200; this._fetchDelay = typeof this.$options.fetchDelay === 'number' ? this.$options.fetchDelay : 200;
Vue.util.defineReactive(this, '$fetchState', {
pending: false,
error: null,
timestamp: Date.now()
});
this.$fetch = $fetch.bind(this); this.$fetch = $fetch.bind(this);
addLifecycleHook(this, 'created', created);
addLifecycleHook(this, 'beforeMount', beforeMount); addLifecycleHook(this, 'beforeMount', beforeMount);
},
data() {
return {
state: {
pending: false,
error: null,
timestamp: Date.now()
}
};
},
computed: {
$fetchState() {
return this.state;
}
} }
}; };
@ -30,29 +35,6 @@ function beforeMount() {
} }
} }
function created() {
if (!isSsrHydration(this)) {
return;
}
// Hydrate component
this._hydrated = true;
this._fetchKey = this.$vnode.elm.dataset.fetchKey;
const data = nuxtState.fetch[this._fetchKey];
// If fetch error
if (data && data._error) {
this.$fetchState.error = data._error;
return;
}
// Merge data
for (const key in data) {
Vue.set(this.$data, key, data[key]);
}
}
function $fetch() { function $fetch() {
if (!this._fetchPromise) { if (!this._fetchPromise) {
this._fetchPromise = $_fetch.call(this) this._fetchPromise = $_fetch.call(this)
@ -65,9 +47,8 @@ function $fetch() {
} }
async function $_fetch() { // eslint-disable-line camelcase async function $_fetch() { // eslint-disable-line camelcase
this.$nuxt.nbFetching++; this.state.pending = true;
this.$fetchState.pending = true; this.state.error = null;
this.$fetchState.error = null;
this._hydrated = false; this._hydrated = false;
let error = null; let error = null;
const startTime = Date.now(); const startTime = Date.now();
@ -87,9 +68,7 @@ async function $_fetch() { // eslint-disable-line camelcase
await new Promise((resolve) => setTimeout(resolve, delayLeft)); await new Promise((resolve) => setTimeout(resolve, delayLeft));
} }
this.$fetchState.error = error; this.state.error = error;
this.$fetchState.pending = false; this.state.pending = false;
this.$fetchState.timestamp = Date.now(); this.state.timestamp = Date.now();
this.$nextTick(() => this.$nuxt.nbFetching--);
} }

View File

@ -1,21 +1,23 @@
const PAGE_ACTION = 'page-action';
const STORE_PAGE_ACTIONS = 'pageActions'; const STORE_PAGE_ACTIONS = 'pageActions';
export default { export default {
created() { created() {
this.updatePageActions(); this.updatePageActions();
this.$nuxt.$on(PAGE_ACTION, (action) => {
const pageActionHandler = (action) => {
if (this.handlePageAction) { if (this.handlePageAction) {
this.handlePageAction(action); this.handlePageAction(action);
} }
}); };
this.$store.commit('pageActionHandler', pageActionHandler);
}, },
beforeDestroy() { unmounted() {
if (this.pageActions) { if (this.pageActions) {
this.$store.commit(STORE_PAGE_ACTIONS, []); this.$store.commit(STORE_PAGE_ACTIONS, []);
} }
this.$nuxt.$off(PAGE_ACTION); this.$store.commit('clearPageActionHandler');
}, },
methods: { methods: {

View File

@ -19,12 +19,6 @@ export default {
// Ensure we re-evaluate the redirect in case this auth provider has been disabled // Ensure we re-evaluate the redirect in case this auth provider has been disabled
const authProvs = await authProvidersInfo(this.$store); const authProvs = await authProvidersInfo(this.$store);
// Nuxt does not remove it's loading indicator - if we are not changing route, then hide it
// https://nuxtjs.org/docs/features/loading/
if (authProvs.enabledLocation) {
this.$nuxt.$loading.finish();
}
next(!authProvs.enabledLocation); next(!authProvs.enabledLocation);
} else { } else {
next(); next();

View File

@ -1,7 +1,3 @@
import Vue from 'vue';
import { isArray } from '@shell/utils/array';
import { classify } from '@shell/plugins/dashboard-store/classify';
import actions from './actions'; import actions from './actions';
import getters from './getters'; import getters from './getters';
import mutations from './mutations'; import mutations from './mutations';
@ -37,7 +33,6 @@ export default (vuexModule, config, init) => {
store.commit(`${ namespace }/applyConfig`, config); store.commit(`${ namespace }/applyConfig`, config);
const module = store._modules.root._children[namespace]; const module = store._modules.root._children[namespace];
const fromServer = window.__NUXT__;
const ctx = new Proxy(module.context, { const ctx = new Proxy(module.context, {
get(obj, key) { get(obj, key) {
@ -52,99 +47,5 @@ export default (vuexModule, config, init) => {
if (init) { if (init) {
init(store, ctx); init(store, ctx);
} }
// Turn all the objects in the store from the server into proxies
const state = fromServer?.state?.[namespace];
if ( state ) {
Object.keys(state.types).forEach((type) => {
const keyField = store.getters[`${ namespace }/keyFieldForType`](type);
const cache = state.types[type];
const map = new Map();
for ( let i = 0 ; i < cache.list.length ; i++ ) {
const proxy = classify(ctx, cache.list[i]);
cache.list[i] = proxy;
map.set(proxy[keyField], proxy);
}
Vue.set(cache, 'map', map);
Vue.set(state.types, type, state.types[type]);
});
}
// Turn all the objects in data from the server into the object from the store;
if ( state && fromServer?.data ) {
fromServer.data = recurse(fromServer.data);
}
if ( state && fromServer?.fetch ) {
fromServer.fetch = recurse(fromServer.fetch);
}
function recurse(obj, parent, key) {
if ( isArray(obj) ) {
const rehydrateKey = `__rehydrateAll__${ key }`;
if ( parent && key && parent[rehydrateKey] ) {
const [ns, type] = parent[rehydrateKey].split('/', 2);
if ( ns === namespace ) {
// Don't delete the key, so that all the stores go through this path,
// and then do nothing if they are not for this namespace,
// instead of doing the else obj.map()
// and breaking the "live" reference to the cache.list array
// delete parent[rehydrateKey];
const cache = state.types[type];
if ( cache ) {
return cache.list;
}
}
} else {
return obj.map((x) => recurse(x));
}
} else if ( obj && typeof obj === 'object' ) {
if ( obj.__rehydrate ) {
if ( obj.__rehydrate !== namespace ) {
// Ignore types that are for another vuex namespace
return obj;
}
const type = obj.type;
const cache = state.types[type];
if ( cache && !obj.__clone ) {
const map = cache.map;
const keyField = store.getters[`${ namespace }/keyFieldForType`](type);
const entry = map.get(obj[keyField]);
// Map the object to the same instance in the store if possible
if ( entry ) {
return entry;
}
}
// Or just return a proxied object
delete obj.__rehydrate;
return classify(ctx, obj);
} else {
for ( const k of Object.keys(obj) ) {
if ( k.startsWith('__rehydrateAll__') ) {
continue;
}
if ( isArray(obj[k]) || typeof obj[k] === 'object' ) {
obj[k] = recurse(obj[k], obj, k);
}
}
}
}
return obj;
}
}; };
}; };

View File

@ -1244,11 +1244,11 @@ export default class Resource {
// ------------------------------------------------------------------ // ------------------------------------------------------------------
currentRoute() { currentRoute() {
return window.$nuxt.$route; return window.$globalApp.$route;
} }
currentRouter() { currentRouter() {
return window.$nuxt.$router; return window.$globalApp.$router;
} }
get listLocation() { get listLocation() {

View File

@ -240,6 +240,7 @@ export const state = () => {
error: null, error: null,
cameFromError: false, cameFromError: false,
pageActions: [], pageActions: [],
pageActionHandler: null,
serverVersion: null, serverVersion: null,
systemNamespaces: [], systemNamespaces: [],
isSingleProduct: undefined, isSingleProduct: undefined,
@ -594,6 +595,14 @@ export const getters = {
}; };
export const mutations = { export const mutations = {
pageActionHandler(state, handler) {
if (handler && typeof handler === 'function') {
state.pageActionHandler = handler;
}
},
clearPageActionHandler(state) {
state.pageActionHandler = null;
},
managementChanged(state, { ready, isRancher }) { managementChanged(state, { ready, isRancher }) {
state.managementReady = ready; state.managementReady = ready;
state.isRancher = isRancher; state.isRancher = isRancher;
@ -691,6 +700,11 @@ export const mutations = {
}; };
export const actions = { export const actions = {
handlePageAction({ state }, action) {
if (state.pageActionHandler) {
state.pageActionHandler(action);
}
},
async loadManagement({ async loadManagement({
getters, state, commit, dispatch, rootGetters getters, state, commit, dispatch, rootGetters
}) { }) {

View File

@ -84,9 +84,9 @@ const setupProgress = (axios) => {
}; };
const $loading = () => { const $loading = () => {
const $nuxt = typeof window !== 'undefined' && window['$nuxt']; const $globalApp = window.$globalApp;
return ($nuxt && $nuxt.$loading && $nuxt.$loading.set) ? $nuxt.$loading : noopLoading; return ($globalApp && $globalApp.$loading && $globalApp.$loading.set) ? $globalApp.$loading : noopLoading;
}; };
let currentRequests = 0; let currentRequests = 0;

View File

@ -258,8 +258,6 @@ export async function setContext(app, context) {
throw new Error('ERR_REDIRECT'); throw new Error('ERR_REDIRECT');
} }
}; };
app.context.nuxtState = window.__NUXT__;
} }
// Dynamic keys // Dynamic keys

View File

@ -1,78 +0,0 @@
import { getMatchedComponents, setScrollRestoration } from './nuxt';
if ('scrollRestoration' in window.history) {
setScrollRestoration('manual');
// reset scrollRestoration to auto when leaving page, allowing page reload
// and back-navigation from other pages to use the browser to restore the
// scrolling position.
window.addEventListener('beforeunload', () => {
setScrollRestoration('auto');
});
// Setting scrollRestoration to manual again when returning to this page.
window.addEventListener('load', () => {
setScrollRestoration('manual');
});
}
function shouldScrollToTop(route) {
const Pages = getMatchedComponents(route);
if (Pages.length === 1) {
const { options = {} } = Pages[0];
return options.scrollToTop !== false;
}
return Pages.some(({ options }) => options && options.scrollToTop);
}
export default function(to, from, savedPosition) {
// If the returned position is falsy or an empty object, will retain current scroll position
let position = false;
const isRouteChanged = to !== from;
// savedPosition is only available for popstate navigations (back button)
if (savedPosition) {
position = savedPosition;
} else if (isRouteChanged && shouldScrollToTop(to)) {
position = { x: 0, y: 0 };
}
const nuxt = window.$nuxt;
if (
// Initial load (vuejs/vue-router#3199)
!isRouteChanged ||
// Route hash changes
(to.path === from.path && to.hash !== from.hash)
) {
nuxt.$nextTick(() => nuxt.$emit('triggerScroll'));
}
return new Promise((resolve) => {
// wait for the out transition to complete (if necessary)
nuxt.$once('triggerScroll', () => {
// coords will be used if no selector is provided,
// or if the selector didn't match any element.
if (to.hash) {
let hash = to.hash;
// CSS.escape() is not supported with IE and Edge.
if (typeof window.CSS !== 'undefined' && typeof window.CSS.escape !== 'undefined') {
hash = `#${ window.CSS.escape(hash.substr(1)) }`;
}
try {
if (document.querySelector(hash)) {
// scroll to anchor by returning the selector
position = { selector: hash };
}
} catch (e) {
console.warn('Failed to save scroll position. Please add CSS.escape() polyfill (https://github.com/mathiasbynens/CSS.escape).'); // eslint-disable-line no-console
}
}
resolve(position);
});
});
}