Skip to content

Commit

Permalink
pkp/pkp-lib#10969 Address breaking change in vue3, where inject in pi…
Browse files Browse the repository at this point in the history
…nia stores does not provide current component provides
  • Loading branch information
jardakotesovec committed Feb 27, 2025
1 parent 8e3368a commit f180108
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 16 deletions.
14 changes: 10 additions & 4 deletions src/composables/useDataChanged.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
import {inject, onUnmounted} from 'vue';
import {onUnmounted} from 'vue';
import {injectFromCurrentInstance} from '@/utils/defineComponentStore';

export function useDataChanged(callback) {
if (callback) {
const registerDataChangeCallback = inject('registerDataChangeCallback');
const registerDataChangeCallback = injectFromCurrentInstance(
'registerDataChangeCallback',
);
registerDataChangeCallback(callback);

const unRegisterDataChangeCallback = inject('unRegisterDataChangeCallback');
const unRegisterDataChangeCallback = injectFromCurrentInstance(
'unRegisterDataChangeCallback',
);

onUnmounted(() => {
unRegisterDataChangeCallback(callback);
});
}

const triggerDataChange = inject('triggerDataChange');
const triggerDataChange = injectFromCurrentInstance('triggerDataChange');

return {triggerDataChange};
}
6 changes: 3 additions & 3 deletions src/composables/useFetch.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {ref, unref, inject} from 'vue';
import {ref, unref} from 'vue';
import {ofetch, createFetch} from 'ofetch';
import {useModalStore} from '@/stores/modalStore';
import {useProgressStore} from '@/stores/progressStore';

import {injectFromCurrentInstance} from '@/utils/defineComponentStore';
import {useDebounceFn} from '@vueuse/core';

let ofetchInstance = ofetch;
Expand Down Expand Up @@ -98,7 +98,7 @@ export function useFetch(url, options = {}) {

let lastRequestController = null;

const modalLevel = inject('modalLevel');
const modalLevel = injectFromCurrentInstance('modalLevel');
const screenName = modalLevel?.value ? `modal_${modalLevel.value}` : 'base';
const progressStore = useProgressStore();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import {inject} from 'vue';
import {defineComponentStore} from '@/utils/defineComponentStore';
import {
defineComponentStore,
injectFromCurrentInstance,
} from '@/utils/defineComponentStore';
import {useForm} from '@/composables/useForm';

export const useWorkflowLogResponseModalStore = defineComponentStore(
'workflowLogResponseModal',
(props) => {
const closeModal = inject('closeModal');
const closeModal = injectFromCurrentInstance('closeModal');
const {set: updateForm, form} = useForm(props.logResponseForm);

function formSuccess() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import {inject, ref, computed, watch} from 'vue';
import {defineComponentStore} from '@/utils/defineComponentStore';
import {ref, computed, watch} from 'vue';
import {
defineComponentStore,
injectFromCurrentInstance,
} from '@/utils/defineComponentStore';
import {useUrl} from '@/composables/useUrl';
import {useFetch} from '@/composables/useFetch';
import {useForm} from '@/composables/useForm';
Expand Down Expand Up @@ -62,7 +65,7 @@ export const useWorkflowChangeSubmissionLanguageModalStore =
// Get publication props
getData();

const closeModal = inject('closeModal');
const closeModal = injectFromCurrentInstance('closeModal');

/**
* Functions
Expand Down
5 changes: 3 additions & 2 deletions src/pages/workflow/workflowStore.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {computed, inject} from 'vue';
import {computed} from 'vue';
import {injectFromCurrentInstance} from '@/utils/defineComponentStore';

import {defineComponentStore} from '@/utils/defineComponentStore';
import {
Expand Down Expand Up @@ -33,7 +34,7 @@ export const useWorkflowStore = defineComponentStore(
/**
* Action to close the workflow from inside
* */
const closeWorkflowModal = inject('closeModal');
const closeWorkflowModal = injectFromCurrentInstance('closeModal');

/**
* Submission & Publication
Expand Down
30 changes: 29 additions & 1 deletion src/utils/defineComponentStore.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,40 @@
import {defineStore, getActivePinia} from 'pinia';
import {onMounted, onBeforeUnmount, provide, inject} from 'vue';
import {
onMounted,
onBeforeUnmount,
provide,
inject,
getCurrentInstance,
} from 'vue';

let storesMap = {};

export function getComponentStoreByName(storeName) {
return storesMap[storeName].useStore();
}

/**
* This is replacement for `inject` method offered from vue, to be used inside pinia "component stores"
* Component stores follow component life cycle for great convinience, but this is not common
* use case. Pinia stores are mostly used as global stores independent from components.
*
* With recent change in vue (https://github.com/vuejs/core/issues/11488),
* inject used within pinia defaults to injecting from root app component provides, instead
* of current instance. Therefore using custom implementation to get current instance provides.
*
*
*/
export function injectFromCurrentInstance(name) {
const instance = getCurrentInstance();
const provides = instance
? instance.parent == null
? instance.vnode.appContext && instance.vnode.appContext.provides
: instance.parent.provides
: void 0;

return provides?.[name];
}

export function defineComponentStore(
_storeName,
setupFn,
Expand Down

0 comments on commit f180108

Please sign in to comment.