From f1fb2eeb87dd1f3c98012a31e3f2cb8fc9f2dd26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vi=CC=81ctor=20CG?= Date: Tue, 23 Jul 2024 16:17:23 +0200 Subject: [PATCH] feat(mixins): removing deprecated mixins --- .../components/decorators/injection.consts.ts | 2 +- .../src/components/dynamic-props.mixin.ts | 33 ---- packages/x-components/src/components/index.ts | 1 - .../src/components/x-component.mixin.ts | 22 --- packages/x-components/src/main.ts | 2 +- packages/x-components/src/plugins/index.ts | 2 - .../src/plugins/x-plugin.alias.ts | 141 ------------------ .../src/plugins/x-plugin.mixin.ts | 113 -------------- packages/x-components/src/plugins/x-plugin.ts | 4 +- .../src/x-installer/x-installer/types.ts | 6 - .../x-installer/x-installer/x-installer.ts | 30 +--- .../device/components/device-detector.vue | 2 +- 12 files changed, 11 insertions(+), 347 deletions(-) delete mode 100644 packages/x-components/src/components/dynamic-props.mixin.ts delete mode 100644 packages/x-components/src/components/x-component.mixin.ts delete mode 100644 packages/x-components/src/plugins/x-plugin.alias.ts delete mode 100644 packages/x-components/src/plugins/x-plugin.mixin.ts diff --git a/packages/x-components/src/components/decorators/injection.consts.ts b/packages/x-components/src/components/decorators/injection.consts.ts index e5adfc14e1..8500abd42e 100644 --- a/packages/x-components/src/components/decorators/injection.consts.ts +++ b/packages/x-components/src/components/decorators/injection.consts.ts @@ -7,7 +7,7 @@ import { ListItem } from '../../utils/types'; * * @example * `const myKey: XInjectKey = 'myFilter';` - * `@XInject(myKey)` + * `inject(myKey)` * * @public */ diff --git a/packages/x-components/src/components/dynamic-props.mixin.ts b/packages/x-components/src/components/dynamic-props.mixin.ts deleted file mode 100644 index 73d9168c1a..0000000000 --- a/packages/x-components/src/components/dynamic-props.mixin.ts +++ /dev/null @@ -1,33 +0,0 @@ -import Vue from 'vue'; -import { PropValidator } from 'vue/types/options'; -import { ExtendedVue } from 'vue/types/vue'; - -/** - * Mixin that creates a string prop in the component for each element - * within the array passed as `propNames` argument. - * - * @param propNames - Array with the names of the props to create. - * @example - * ```typescript - * - * @Component({ - * components: { RelatedTag }, - * mixins: [xComponentMixin(relatedTagsXModule)] - * }) - * export default class RelatedTags extends Mixins(dynamicPropsMixin(['list', 'li', 'tag'])) { - * // This component will have available 3 props: 'list', 'li' and 'tag' - * } - * ``` - * @returns Mixin for the component. - * @deprecated Use props. - */ -export function dynamicPropsMixin( - propNames: PropNames[] -): ExtendedVue>> { - return Vue.extend({ - props: propNames.reduce( - (props, propName) => ({ ...props, [propName]: { type: String } }), - {} as Record> - ) - }); -} diff --git a/packages/x-components/src/components/index.ts b/packages/x-components/src/components/index.ts index 6b479c4ff5..911e226bae 100644 --- a/packages/x-components/src/components/index.ts +++ b/packages/x-components/src/components/index.ts @@ -31,5 +31,4 @@ export { default as PageLoaderButton } from './page-loader-button.vue'; // Utils export * from './decorators/injection.consts'; -export * from './x-component.mixin'; export * from './x-component.utils'; diff --git a/packages/x-components/src/components/x-component.mixin.ts b/packages/x-components/src/components/x-component.mixin.ts deleted file mode 100644 index e879c17b1b..0000000000 --- a/packages/x-components/src/components/x-component.mixin.ts +++ /dev/null @@ -1,22 +0,0 @@ -import Vue, { ComponentOptions } from 'vue'; -import { XPlugin } from '../plugins/x-plugin'; -import { AnyXModule } from '../x-modules/x-modules.types'; - -/** - * Initializes a component as an X-Component: - * * Registers the module passed as parameter. - * * Flags the component as X-Component, so then it can be detected with the {@link isXComponent} - * function. - * - * @param module - The module associated to the X-Component using this mixin. - * @returns Mixin for the module. - * @public - * @deprecated Use `XPlugin.registerXModule(xModule)` or `initialXModules` in - * {@link InstallXOptions | x-installer} instead. - */ -export function xComponentMixin(module: AnyXModule): ComponentOptions { - XPlugin.registerXModule(module); - return { - xModule: module.name - }; -} diff --git a/packages/x-components/src/main.ts b/packages/x-components/src/main.ts index fb81f43072..37774f5136 100644 --- a/packages/x-components/src/main.ts +++ b/packages/x-components/src/main.ts @@ -26,7 +26,7 @@ const installer = new XInstaller({ rootComponent: AppComponent, domElement: '#app', onCreateApp: initDevtools, - async installExtraPlugins({ app }) { + installExtraPlugins({ app }) { app.use(router); } }); diff --git a/packages/x-components/src/plugins/index.ts b/packages/x-components/src/plugins/index.ts index 0b10c1e395..bc0a003cbc 100644 --- a/packages/x-components/src/plugins/index.ts +++ b/packages/x-components/src/plugins/index.ts @@ -1,8 +1,6 @@ export * from './devtools/devtools.plugin'; export * from './x-bus'; export * from './x-emitters'; -export * from './x-plugin.alias'; -export * from './x-plugin.mixin'; export * from './x-plugin'; export * from './x-plugin.types'; export * from './x-plugin.utils'; diff --git a/packages/x-components/src/plugins/x-plugin.alias.ts b/packages/x-components/src/plugins/x-plugin.alias.ts deleted file mode 100644 index e070660666..0000000000 --- a/packages/x-components/src/plugins/x-plugin.alias.ts +++ /dev/null @@ -1,141 +0,0 @@ -import Vue from 'vue'; -import { RequestStatus } from '../store/utils/status-store.utils'; -import { - XComponentAliasAPI, - XComponentAliasQueryAPI, - XComponentAliasStatusAPI -} from './x-plugin.types'; -import { getGetterPath } from './x-plugin.utils'; - -/** - * Creates an object containing the alias part of {@link XComponentAPI}. - * - * @param component - The component with the store from which retrieve the data. - * @returns An object containing the alias part of the {@link XComponentAPI}. - * - * @internal - */ -export function getAliasAPI(component: Vue): XComponentAliasAPI { - const queryModules = [ - 'facets', - 'searchBox', - 'nextQueries', - 'querySuggestions', - 'relatedTags', - 'search' - ] as const; - const statusModules = [ - 'identifierResults', - 'nextQueries', - 'popularSearches', - 'querySuggestions', - 'recommendations', - 'relatedTags', - 'search' - ] as const; - - const query = queryModules.reduce((acc, moduleName) => { - return Object.defineProperty(acc, moduleName, { - get(): string { - return component.$store.state.x[moduleName]?.query ?? ''; - }, - enumerable: true - }); - }, {} as XComponentAliasQueryAPI); - const status = statusModules.reduce((acc, moduleName) => { - return Object.defineProperty(acc, moduleName, { - get(): RequestStatus | undefined { - return component.$store.state.x[moduleName]?.status; - }, - enumerable: true - }); - }, {} as XComponentAliasStatusAPI); - - return { - query, - status, - get device() { - return component.$store.state.x.device?.name ?? null; - }, - get facets() { - return component.$store.getters[getGetterPath('facets', 'facets')] ?? {}; - }, - get historyQueries() { - return component.$store.getters[getGetterPath('historyQueries', 'historyQueries')] ?? []; - }, - get historyQueriesWithResults() { - return ( - component.$store.getters[getGetterPath('historyQueries', 'historyQueriesWithResults')] ?? [] - ); - }, - get fullHistoryQueries() { - return component.$store.state.x.historyQueries?.historyQueries ?? []; - }, - get isHistoryQueriesEnabled() { - return component.$store.state.x.historyQueries?.isEnabled ?? false; - }, - get fromNoResultsWithFilters() { - return component.$store.state.x.search?.fromNoResultsWithFilters ?? false; - }, - get identifierResults() { - return component.$store.state.x.identifierResults?.identifierResults ?? []; - }, - get searchBoxStatus() { - return component.$store.state.x.searchBox?.inputStatus ?? undefined; - }, - get isEmpathizeOpen() { - return component.$store.state.x.empathize?.isOpen ?? false; - }, - get nextQueries() { - return component.$store.getters[getGetterPath('nextQueries', 'nextQueries')] ?? []; - }, - get noResults() { - return component.$store.state.x.search?.isNoResults ?? false; - }, - get partialResults() { - return component.$store.state.x.search?.partialResults ?? []; - }, - get popularSearches() { - return component.$store.state.x.popularSearches?.popularSearches ?? []; - }, - get querySuggestions() { - return component.$store.getters[getGetterPath('querySuggestions', 'querySuggestions')] ?? []; - }, - get fullQuerySuggestions() { - return component.$store.state.x.querySuggestions?.suggestions ?? []; - }, - get recommendations() { - return component.$store.state.x.recommendations?.recommendations ?? []; - }, - get redirections() { - return component.$store.state.x.search?.redirections ?? []; - }, - get relatedTags() { - return component.$store.getters[getGetterPath('relatedTags', 'relatedTags')] ?? []; - }, - get results() { - return component.$store.state.x.search?.results ?? []; - }, - get scroll() { - return component.$store.state.x.scroll?.data ?? {}; - }, - get selectedFilters() { - return component.$store.getters[getGetterPath('facets', 'selectedFilters')] ?? []; - }, - get selectedRelatedTags() { - return component.$store.state.x.relatedTags?.selectedRelatedTags ?? []; - }, - get semanticQueries() { - return component.$store.state.x.semanticQueries?.semanticQueries ?? []; - }, - get spellcheckedQuery() { - return component.$store.state.x.search?.spellcheckedQuery ?? null; - }, - get totalResults() { - return component.$store.state.x.search?.totalResults ?? 0; - }, - get selectedSort() { - return component.$store.state.x.search?.sort ?? ''; - } - }; -} diff --git a/packages/x-components/src/plugins/x-plugin.mixin.ts b/packages/x-components/src/plugins/x-plugin.mixin.ts deleted file mode 100644 index 512781ce68..0000000000 --- a/packages/x-components/src/plugins/x-plugin.mixin.ts +++ /dev/null @@ -1,113 +0,0 @@ -import Vue, { ComponentOptions } from 'vue'; -import { Store } from 'vuex'; -import { XBus } from '@empathyco/x-bus'; -import { getRootXComponent, getXComponentXModuleName } from '../components/x-component.utils'; -import { RootXStoreState } from '../store/store.types'; -import { XEvent, XEventPayload, XEventsTypes } from '../wiring/events.types'; -import { WireMetadata } from '../wiring/wiring.types'; -import { FeatureLocation } from '../types/origin'; -import { XModuleName } from '../x-modules/x-modules.types'; -import { getAliasAPI } from './x-plugin.alias'; -import { XComponentAPI, XComponentBusAPI } from './x-plugin.types'; - -declare module 'vue/types/vue' { - export interface Vue { - $x: XComponentAPI; - } -} - -declare module 'vue/types/options' { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - export interface ComponentOptions { - xModule?: XModuleName; - } -} - -interface PrivateExtendedVueComponent extends Vue { - $location?: FeatureLocation; - $store: Store<{ x: Partial }>; - xComponent: Vue | undefined; -} - -/** - * Vue global mixin that adds a `$x` object to every component with the {@link XComponentAPI}. - * - * @remarks It adds an injection property `origin` which value is included in the metadata of each - * event emitted with `$x.emit`. - * - * @param bus - The {@link @empathyco/x-bus#XBus} to use inside the components for emitting events. - * @returns Mixin options which registers the component as X-Component and the $x. - * @internal - */ -export const createXComponentAPIMixin = ( - bus: XBus -): ComponentOptions & ThisType => ({ - inject: { - $location: { - from: 'location', - default: undefined - } - }, - beforeCreate(this: PrivateExtendedVueComponent) { - this.xComponent = getRootXComponent(this); - const aliasAPI = getAliasAPI(this); - const busAPI = getBusAPI(bus, this); - this.$x = Object.assign(aliasAPI, busAPI); - } -}); - -/** - * Creates an object containing the API related to the {@link @empathyco/x-bus#XBus}. - * - * @param bus - The global {@link @empathyco/x-bus#XBus}. - * @param component - The component instance. - * - * @returns An object containing the {@link XComponentBusAPI}. - * @internal - */ -export function getBusAPI( - bus: XBus, - component: PrivateExtendedVueComponent -): XComponentBusAPI { - return { - emit: ( - event: Event, - payload?: XEventPayload, - metadata: Omit = {} - ) => { - bus.emit(event, payload as XEventPayload, createWireMetadata(component, metadata)); - component.xComponent?.$emit(event, payload); - }, - on: bus.on.bind(bus) - }; -} - -/** - * Creates a wire metadata object based on the component and the provided metadata. - * - * @param component - The component this metadata belongs to. - * @param metadata - Additional metadata emitted by the component. - * @returns A {@link WireMetadata} object. - * @internal - */ -function createWireMetadata( - component: PrivateExtendedVueComponent, - metadata: Partial -): WireMetadata { - return Object.defineProperties( - { - replaceable: true, - moduleName: getXComponentXModuleName(component.xComponent), - location: component.$location, - ...metadata - }, - { - component: { - value: component, - /* FIX-ME: defining component as a non-enumerable property to ease tests changes due to - * cyclic dependencies in Vue component instances. */ - enumerable: false - } - } - ); -} diff --git a/packages/x-components/src/plugins/x-plugin.ts b/packages/x-components/src/plugins/x-plugin.ts index e518ef1c12..fb1e8b124d 100644 --- a/packages/x-components/src/plugins/x-plugin.ts +++ b/packages/x-components/src/plugins/x-plugin.ts @@ -14,7 +14,6 @@ import { AnyXModule, XModuleName } from '../x-modules/x-modules.types'; import { sendWiringToDevtools } from './devtools/wiring.devtools'; import { bus } from './x-bus'; import { registerStoreEmitters } from './x-emitters'; -import { createXComponentAPIMixin } from './x-plugin.mixin'; import { AnyXStoreModuleOption, XModuleOptions, XPluginOptions } from './x-plugin.types'; import { assertXPluginOptionsAreValid } from './x-plugin.utils'; @@ -138,10 +137,9 @@ export class XPlugin { * @internal */ protected store!: Store; + /** * The Vue application instance, passed by the installation method. - * {@link createXComponentAPIMixin}, and install the {@link https://vuex.vuejs.org/ | Vuex} - * plugin. * * @internal */ diff --git a/packages/x-components/src/x-installer/x-installer/types.ts b/packages/x-components/src/x-installer/x-installer/types.ts index 9d308b8492..dedf6e3a5d 100644 --- a/packages/x-components/src/x-installer/x-installer/types.ts +++ b/packages/x-components/src/x-installer/x-installer/types.ts @@ -16,10 +16,6 @@ export interface InstallXOptions extends XPluginOptions * initialized, only plugin installed. */ rootComponent?: Component; - /** - * The Vue application instance. If it is not passed, a new Vue application is created. - */ - app?: App; /** * The API to expose globally. If is not passed the default {@link BaseXAPI} will be used. If * a `false` value is passed then the API is not created. @@ -40,7 +36,6 @@ export interface InstallXOptions extends XPluginOptions * installed. */ plugin?: Plugin; - /** * Callback to invoke after instantiating the app. * @@ -64,7 +59,6 @@ export interface InstallXOptions extends XPluginOptions */ export interface ExtraPluginsOptions { /** The Vue application instance that is being used. */ - app: App; /** The events bus instance used to communicate different part of the x-components. */ bus: XBus; diff --git a/packages/x-components/src/x-installer/x-installer/x-installer.ts b/packages/x-components/src/x-installer/x-installer/x-installer.ts index d2e45aa674..5e03672ee7 100644 --- a/packages/x-components/src/x-installer/x-installer/x-installer.ts +++ b/packages/x-components/src/x-installer/x-installer/x-installer.ts @@ -170,11 +170,11 @@ export class XInstaller { const plugin = this.installPlugin(pluginOptions, bus); await this.installExtraPlugins(bus); this.api?.setBus(bus); - this.getApp().mount(this.getMountingTarget(this.options.domElement)); + this.app.mount(this.getMountingTarget(this.options.domElement)); return { api: this.api, - app: this.getApp(), + app: this.app, bus, plugin }; @@ -214,22 +214,6 @@ export class XInstaller { return this.options.bus ?? bus; } - /** - * This method returns the Vue app instance. - * It returns the `app` parameter in the {@link InstallXOptions} or if not provided, then - * returns a newly created instance. - * - * @remarks The purpose of this option is mainly the testing. In a test we can use this option - * to pass the local vue instance created by `createLocalVue` method. - * - * @returns App - A Vue app instance. - * - * @internal - */ - protected getApp(): App { - return this.options.app ?? this.app; - } - /** * Creates and install the Vue Plugin. If `plugin` parameter is passed in the * {@link InstallXOptions}, then it is used. If not, then a new instance of {@link XPlugin} is @@ -247,7 +231,7 @@ export class XInstaller { bus: XBus ): Plugin { const plugin = this.options.plugin ?? new XPlugin(bus); - this.getApp().use(plugin, pluginOptions); + this.app.use(plugin, pluginOptions); return plugin; } @@ -261,18 +245,18 @@ export class XInstaller { */ protected installExtraPlugins(bus: XBus): Promise { return Promise.resolve( - this.options.installExtraPlugins?.({ app: this.getApp(), snippet: this.snippetConfig!, bus }) + this.options.installExtraPlugins?.({ app: this.app, snippet: this.snippetConfig!, bus }) ); } /** - * In the case that the `rootComponent` parameter is present in the {@link InstallXOptions}, then a new Vue - * application is created using that component as root. + * In the case that the `rootComponent` parameter is present in the {@link InstallXOptions}, + * then a new Vue application is created using that component as root. * * @internal */ protected createApp(): void { - if (!this.options.app && this.options.rootComponent !== undefined) { + if (this.options.rootComponent !== undefined) { this.app = createApp(this.options.rootComponent); this.app.provide('snippetConfig', this.snippetConfig); this.options.onCreateApp?.(this.app); diff --git a/packages/x-components/src/x-modules/device/components/device-detector.vue b/packages/x-components/src/x-modules/device/components/device-detector.vue index 5428c671c1..6a6bceb930 100644 --- a/packages/x-components/src/x-modules/device/components/device-detector.vue +++ b/packages/x-components/src/x-modules/device/components/device-detector.vue @@ -4,7 +4,7 @@