Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
- Add API for component registry from plugins
- Expose vue module globally
  • Loading branch information
jardakotesovec committed Nov 9, 2023
1 parent b0be24e commit 9c70176
Show file tree
Hide file tree
Showing 2 changed files with 151 additions and 89 deletions.
39 changes: 39 additions & 0 deletions js/classes/VueRegistry.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ export default {
*/
_instances: {},

/**
* Registry of all global components
*/
_globalComponents: {},

/**
* Initialize a Vue controller
*
Expand Down Expand Up @@ -62,4 +67,38 @@ export default {
}
});
},

/**
* Keeps track of all globally registered vue components
*
* This is important especially for plugins with custom vue components
* All global components gets automatically registered for each vue instance thats created
* It has same signature as vueInstance.component()
* @param string componentName
* @param object component
*/
registerComponent(componentName, component) {
this._globalComponents[componentName] = component;
},

/**
* Allow possibility to allow retrive component object
*
* Should be needed very rarely. This is important for some plugins which currently extends existing component, like FieldPubIdUrn
* @param string Able to retrieve component object
*/
getComponent(componentName) {
return this._globalComponents[componentName];
},

/**
* Provides all globaly registered components
*
* Main reason is to be able get all components to be registered in lib/pkp/load.js
* for every vue instance which is created
* @returns object Object of all components, where key is component name and value component object
*/
getAllComponents() {
return this._globalComponents;
},
};
201 changes: 112 additions & 89 deletions js/load.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@

// Vue lib and custom mixins
import {createApp} from 'vue';
import {createPinia} from 'pinia'
import * as vue from 'vue';

import {createPinia} from 'pinia';
import GlobalMixins from '@/mixins/global.js';
import VueAnnouncer from '@vue-a11y/announcer';
import FloatingVue from 'floating-vue';
Expand Down Expand Up @@ -99,18 +100,116 @@ import ListPanel from '@/components/ListPanel/ListPanel.vue';
import VueRegistry from './classes/VueRegistry.js';
import i18nPlugin from '@/piniaPlugins/i18n.plugin.js';

// Register global components
VueRegistry.registerComponent('Badge', Badge);
VueRegistry.registerComponent('PkpBadge', Badge);
VueRegistry.registerComponent('Dropdown', Dropdown);
VueRegistry.registerComponent('PkpDropdown', Dropdown);
VueRegistry.registerComponent('Icon', Icon);
VueRegistry.registerComponent('PkpIcon', Icon);
VueRegistry.registerComponent('Notification', Notification);
VueRegistry.registerComponent('PkpNotification', Notification);
VueRegistry.registerComponent('Panel', Panel);
VueRegistry.registerComponent('PkpPanel', Panel);
VueRegistry.registerComponent('PanelSection', PanelSection);
VueRegistry.registerComponent('PkpPanelSection', PanelSection);
VueRegistry.registerComponent('PkpButton', PkpButton);
VueRegistry.registerComponent('PkpHeader', PkpHeader);
VueRegistry.registerComponent('Spinner', Spinner);
VueRegistry.registerComponent('PkpSpinner', Spinner);
VueRegistry.registerComponent('Step', Step);
VueRegistry.registerComponent('PkpStep', Step);
VueRegistry.registerComponent('Steps', Steps);
VueRegistry.registerComponent('PkpSteps', Steps);
VueRegistry.registerComponent('Tab', Tab);
VueRegistry.registerComponent('PkpTab', Tab);
VueRegistry.registerComponent('Tabs', Tabs);
VueRegistry.registerComponent('PkpTabs', Tabs);

// Register other components
VueRegistry.registerComponent('PkpActionPanel', ActionPanel);
VueRegistry.registerComponent('PkpButtonRow', ButtonRow);
VueRegistry.registerComponent('PkpDoughnutChart', DoughnutChart);
VueRegistry.registerComponent('PkpLineChart', LineChart);
VueRegistry.registerComponent('PkpComposer', Composer);
VueRegistry.registerComponent('PkpDateRange', DateRange);
VueRegistry.registerComponent('PkpFile', File);
VueRegistry.registerComponent('PkpFileAttacher', FileAttacher);
VueRegistry.registerComponent('PkpFileUploader', FileUploader);
VueRegistry.registerComponent('PkpFileUploadProgress', FileUploadProgress);
VueRegistry.registerComponent('PkpFilter', PkpFilter);
VueRegistry.registerComponent('PkpFilterAutosuggest', FilterAutosuggest);
VueRegistry.registerComponent('PkpFilterSlider', FilterSlider);
VueRegistry.registerComponent(
'PkpFilterSliderMultirange',
FilterSliderMultirange,
);
VueRegistry.registerComponent('PkpList', List);
VueRegistry.registerComponent('PkpListItem', ListItem);
VueRegistry.registerComponent('PkpModal', Modal);
VueRegistry.registerComponent('PkpMultilingualProgress', MultilingualProgress);
VueRegistry.registerComponent('PkpOrderer', Orderer);
VueRegistry.registerComponent('PkpPagination', Pagination);
VueRegistry.registerComponent('PkpProgressBar', ProgressBar);
VueRegistry.registerComponent('PkpSearch', Search);
VueRegistry.registerComponent('PkpTable', Table);
VueRegistry.registerComponent('PkpTableCell', TableCell);
VueRegistry.registerComponent('PkpTooltip', Tooltip);

// Register Form components
VueRegistry.registerComponent('PkpForm', Form);
VueRegistry.registerComponent('PkpFieldArchivingPn', FieldArchivingPn);
VueRegistry.registerComponent(
'PkpFieldAutosuggestPreset',
FieldAutosuggestPreset,
);
VueRegistry.registerComponent('PkpFieldBase', FieldBase);
VueRegistry.registerComponent('PkpFieldBaseAutosuggest', FieldBaseAutosuggest);
VueRegistry.registerComponent('PkpFieldColor', FieldColor);
VueRegistry.registerComponent('PkpFieldControlledVocab', FieldControlledVocab);
VueRegistry.registerComponent('PkpFieldHtml', FieldHtml);
VueRegistry.registerComponent('PkpFieldMetadataSetting', FieldMetadataSetting);
VueRegistry.registerComponent('PkpFieldOptions', FieldOptions);
VueRegistry.registerComponent('PkpFieldPreparedContent', FieldPreparedContent);
VueRegistry.registerComponent('PkpFieldPubId', FieldPubId);
VueRegistry.registerComponent('PkpFieldRadioInput', FieldRadioInput);
VueRegistry.registerComponent('PkpFieldRichText', FieldRichText);
VueRegistry.registerComponent('PkpFieldRichTextarea', FieldRichTextarea);
VueRegistry.registerComponent('PkpFieldSelect', FieldSelect);
VueRegistry.registerComponent('PkpFieldSelectIssue', FieldSelectIssue);
VueRegistry.registerComponent('PkpFieldSelectIssues', FieldSelectIssues);
VueRegistry.registerComponent(
'PkpFieldSelectSubmissions',
FieldSelectSubmissions,
);
VueRegistry.registerComponent('PkpFieldSelectUsers', FieldSelectUsers);
VueRegistry.registerComponent(
'PkpFieldShowEnsuringLink',
FieldShowEnsuringLink,
);
VueRegistry.registerComponent('PkpFieldText', FieldText);
VueRegistry.registerComponent('PkpFieldTextarea', FieldTextarea);
VueRegistry.registerComponent('PkpFieldUpload', FieldUpload);
VueRegistry.registerComponent('PkpFieldUploadImage', FieldUploadImage);

// Required by the URN plugin, to be migrated at some point to pkp prefix
VueRegistry.registerComponent('field-text', FieldText);
VueRegistry.registerComponent('field-pub-id', FieldPubId);

// Register ListPanel
VueRegistry.registerComponent('PkpListPanel', ListPanel);

function pkpCreateVueApp(createAppArgs) {
// Initialize Vue
const vueApp = createApp(createAppArgs);
const pinia = createPinia(i18nPlugin);
pinia.use(i18nPlugin)
pinia.use(i18nPlugin);
vueApp.use(pinia);

// https://github.com/vuejs/pinia/discussions/1197
// to be able globally share stores
vueApp.config.globalProperties.$store = {};


// For compatibility with vue2 to preserve spaces between html tags
vueApp.config.compilerOptions.whitespace = 'preserve';
vueApp.use(VueScrollTo);
Expand All @@ -130,98 +229,22 @@ function pkpCreateVueApp(createAppArgs) {

vueApp.mixin(GlobalMixins);

// Register global components
vueApp.component('Badge', Badge);
vueApp.component('PkpBadge', Badge);
vueApp.component('Dropdown', Dropdown);
vueApp.component('PkpDropdown', Dropdown);
vueApp.component('Icon', Icon);
vueApp.component('PkpIcon', Icon);
vueApp.component('Notification', Notification);
vueApp.component('PkpNotification', Notification);
vueApp.component('Panel', Panel);
vueApp.component('PkpPanel', Panel);
vueApp.component('PanelSection', PanelSection);
vueApp.component('PkpPanelSection', PanelSection);
vueApp.component('PkpButton', PkpButton);
vueApp.component('PkpHeader', PkpHeader);
vueApp.component('Spinner', Spinner);
vueApp.component('PkpSpinner', Spinner);
vueApp.component('Step', Step);
vueApp.component('PkpStep', Step);
vueApp.component('Steps', Steps);
vueApp.component('PkpSteps', Steps);
vueApp.component('Tab', Tab);
vueApp.component('PkpTab', Tab);
vueApp.component('Tabs', Tabs);
vueApp.component('PkpTabs', Tabs);

// Register other components
vueApp.component('PkpActionPanel', ActionPanel);
vueApp.component('PkpButtonRow', ButtonRow);
vueApp.component('PkpDoughnutChart', DoughnutChart);
vueApp.component('PkpLineChart', LineChart);
vueApp.component('PkpComposer', Composer);
vueApp.component('PkpDateRange', DateRange);
vueApp.component('PkpFile', File);
vueApp.component('PkpFileAttacher', FileAttacher);
vueApp.component('PkpFileUploader', FileUploader);
vueApp.component('PkpFileUploadProgress', FileUploadProgress);
vueApp.component('PkpFilter', PkpFilter);
vueApp.component('PkpFilterAutosuggest', FilterAutosuggest);
vueApp.component('PkpFilterSlider', FilterSlider);
vueApp.component('PkpFilterSliderMultirange', FilterSliderMultirange);
vueApp.component('PkpList', List);
vueApp.component('PkpListItem', ListItem);
vueApp.component('PkpModal', Modal);
vueApp.component('PkpMultilingualProgress', MultilingualProgress);
vueApp.component('PkpOrderer', Orderer);
vueApp.component('PkpPagination', Pagination);
vueApp.component('PkpProgressBar', ProgressBar);
vueApp.component('PkpSearch', Search);
vueApp.component('PkpTable', Table);
vueApp.component('PkpTableCell', TableCell);
vueApp.component('PkpTooltip', Tooltip);

// Register Form components
vueApp.component('PkpForm', Form);
vueApp.component('PkpFieldArchivingPn', FieldArchivingPn);
vueApp.component('PkpFieldAutosuggestPreset', FieldAutosuggestPreset);
vueApp.component('PkpFieldBase', FieldBase);
vueApp.component('PkpFieldBaseAutosuggest', FieldBaseAutosuggest);
vueApp.component('PkpFieldColor', FieldColor);
vueApp.component('PkpFieldControlledVocab', FieldControlledVocab);
vueApp.component('PkpFieldHtml', FieldHtml);
vueApp.component('PkpFieldMetadataSetting', FieldMetadataSetting);
vueApp.component('PkpFieldOptions', FieldOptions);
vueApp.component('PkpFieldPreparedContent', FieldPreparedContent);
vueApp.component('PkpFieldPubId', FieldPubId);
vueApp.component('PkpFieldRadioInput', FieldRadioInput);
vueApp.component('PkpFieldRichText', FieldRichText);
vueApp.component('PkpFieldRichTextarea', FieldRichTextarea);
vueApp.component('PkpFieldSelect', FieldSelect);
vueApp.component('PkpFieldSelectIssue', FieldSelectIssue);
vueApp.component('PkpFieldSelectIssues', FieldSelectIssues);
vueApp.component('PkpFieldSelectSubmissions', FieldSelectSubmissions);
vueApp.component('PkpFieldSelectUsers', FieldSelectUsers);
vueApp.component('PkpFieldShowEnsuringLink', FieldShowEnsuringLink);
vueApp.component('PkpFieldText', FieldText);
vueApp.component('PkpFieldTextarea', FieldTextarea);
vueApp.component('PkpFieldUpload', FieldUpload);
vueApp.component('PkpFieldUploadImage', FieldUploadImage);

// Required by the URN plugin, to be migrated at some point to pkp prefix
vueApp.component('field-text', FieldText);
vueApp.component('field-pub-id', FieldPubId);

// Register ListPanel
vueApp.component('PkpListPanel', ListPanel);
// register all global components
const allGlobalComponents = VueRegistry.getAllComponents();
Object.keys(allGlobalComponents).forEach((componentName) => {
vueApp.component(componentName, allGlobalComponents[componentName]);
});

return vueApp;
}

export default {
Vue: pkpCreateVueApp({}),
// making vue functions available via pkp.modules.vue for plugins
// especially useful when using composition api
modules: {
vue,
},
pkpCreateVueApp,
createApp,
registry: VueRegistry,
Expand Down

0 comments on commit 9c70176

Please sign in to comment.