Skip to content

Commit

Permalink
feat(extra-params): migrate extra params and snippet config extra par…
Browse files Browse the repository at this point in the history
…ams (#1531)
  • Loading branch information
diegopf authored Jun 24, 2024
1 parent 79e2c9a commit d869f18
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 130 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<template>
<SnippetConfigExtraParams :values="{ catalog: 'empathy' }" />
{{ params }}
</template>
<script setup lang="ts">
import { provide } from 'vue';
import SnippetConfigExtraParams from '../../../../x-components/src/x-modules/extra-params/components/snippet-config-extra-params.vue';
import { useState } from '../../../../x-components/src/composables/use-state';
const snippetConfig = window.InterfaceX?.getSnippetConfig();
provide('snippetConfig', snippetConfig);
const { params } = useState('extraParams', ['params']);
window.InterfaceX?.setSnippetConfig({ store: 'demo', lang: 'es', warehouse: 1234 });
</script>
1 change: 1 addition & 0 deletions packages/_vue3-migration-test/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ export { default as TestBasePanel } from './panels/test-base-panel.vue';
export { default as TestBaseKeyboardNavigation } from './test-base-keyboard-navigation.vue';
export { default as TestBaseEventsModal } from './modals/test-base-events-modal.vue';
export { default as TestBaseIdModal } from './modals/test-base-id-modal.vue';
export { default as TestExtraParams } from './extra-params/test-extra-params.vue';
44 changes: 27 additions & 17 deletions packages/_vue3-migration-test/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { QuerySuggestionsRequest, XComponentsAdapter } from '@empathyco/x-types';
import { Component, configureCompat, createApp } from 'vue';
import { createStore } from 'vuex';
import { xPlugin } from '../../x-components/src/plugins/x-plugin';
import { getRelatedTagsStub } from '../../x-components/src/__stubs__/related-tags-stubs.factory';
import { getQuerySuggestionsStub } from '../../x-components/src/__stubs__/query-suggestions-stubs.factory';
import {
createResultStub,
getBannersStub,
getNextQueriesStub,
getPromotedsStub,
getResultsStub
} from '../../x-components/src/__stubs__/index';
import { XInstaller } from '../../x-components/src/x-installer/x-installer/x-installer';
import App from './App.vue';
import router from './router';
import {
Expand Down Expand Up @@ -77,27 +78,36 @@ const adapter = {
promoteds: getPromotedsStub(),
banners: getBannersStub()
});
})
}),
identifierResults: () =>
new Promise(resolve =>
resolve({ results: ['123A', '123B', '123C', '123D'].map(id => createResultStub(id)) })
)
} as unknown as XComponentsAdapter;

const store = createStore({});

createApp(App as Component)
.use(router)
.use(store)
.use(xPlugin, {
adapter,
store,
__PRIVATE__xModules: {
facets: facetsXModule,
nextQueries: nextQueriesXModule,
scroll: scrollXModule,
search: searchXModule,
queriesPreview: queriesPreviewXModule,
semanticQueries: semanticQueriesXModule,
recommendations: recommendationsXModule,
popularSearches: popularSearchesXModule,
identifierResults: identifierResultsXModule
}
})
.mount('#app');

window.initX = {
instance: 'empathy',
lang: 'en'
};
new XInstaller({
adapter,
store,
__PRIVATE__xModules: {
facets: facetsXModule,
nextQueries: nextQueriesXModule,
scroll: scrollXModule,
search: searchXModule,
queriesPreview: queriesPreviewXModule,
semanticQueries: semanticQueriesXModule,
recommendations: recommendationsXModule,
identifierResults: identifierResultsXModule,
popularSearches: popularSearchesXModule
}
}).init();
8 changes: 7 additions & 1 deletion packages/_vue3-migration-test/src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ import {
TestRecommendations,
TestPopularSearches,
TestNextQueries,
TestIdentifierResults
TestIdentifierResults,
TestExtraParams
} from './';

const routes = [
Expand Down Expand Up @@ -242,6 +243,11 @@ const routes = [
path: '/identifier-results',
name: 'IdentifierResults',
component: TestIdentifierResults
},
{
path: '/snippet-config-extraparams',
name: 'SnippetConfigExtraparams',
component: TestExtraParams
}
];

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { PrivateXModuleOptions } from '../../../../x-components/src/plugins/x-plugin.types';
import { IdentifierResultsXModule } from '../../../../x-components/src/x-modules/identifier-results/x-module';
import { createResultStub } from '../../../../x-components/src/__stubs__/results-stubs.factory';

export const identifierResultsXModule: PrivateXModuleOptions<IdentifierResultsXModule> = {
storeModule: {
Expand All @@ -11,7 +10,7 @@ export const identifierResultsXModule: PrivateXModuleOptions<IdentifierResultsXM
identifierDetectionRegexp: '^[0-9]{2,}$',
separatorChars: '-/ '
},
identifierResults: ['123A', '123B', '123C', '123D'].map(id => createResultStub(id)),
identifierResults: [],
origin: null,
query: 'test',
params: {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ describe('testing extra params component', () => {

expect(extraParamsProvidedCallback).toHaveBeenCalledWith<[WirePayload<Dictionary<unknown>>]>({
eventPayload: { warehouse: 1234 },
metadata: { moduleName: 'extraParams', location: undefined, replaceable: true }
metadata: { moduleName: 'extraParams', location: 'none', replaceable: true }
});
expect(extraParamsProvidedCallback).toHaveBeenCalledTimes(1);

await wrapper.setProps({ values: { warehouse: 5678 } });

expect(extraParamsProvidedCallback).toHaveBeenCalledWith<[WirePayload<Dictionary<unknown>>]>({
eventPayload: { warehouse: 5678 },
metadata: { moduleName: 'extraParams', location: undefined, replaceable: true }
metadata: { moduleName: 'extraParams', location: 'none', replaceable: true }
});
expect(extraParamsProvidedCallback).toHaveBeenCalledTimes(2);
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,50 +1,44 @@
<script lang="ts">
import { Dictionary } from '@empathyco/x-utils';
import Vue from 'vue';
import { Component, Prop } from 'vue-property-decorator';
import { State, xComponentMixin, XEmit } from '../../../components';
import { defineComponent, PropType, watch } from 'vue';
import { extraParamsXModule } from '../x-module';
import { use$x } from '../../../composables/use-$x';
import { useState } from '../../../composables/use-state';
/**
* It emits a {@link ExtraParamsXEvents.ExtraParamsProvided} with the values
* received as a prop.
*
* @public
*/
@Component({
mixins: [xComponentMixin(extraParamsXModule)]
})
export default class ExtraParams extends Vue {
/**
* Emits the initial extra params, overriding with the state extra params, just in case, those
* values were already set by XComponents initialization (url, plugin config, etc.).
*/
created(): void {
this.$x.emit('ExtraParamsInitialized', { ...this.values });
this.$x.emit('ExtraParamsProvided', { ...this.values, ...this.storeExtraParams });
}
/**
* (Required) A Dictionary where the keys are the extra param names and its values.
*
* @remarks Emits the {@link ExtraParamsXEvents.ExtraParamsProvided} when the
* component is rendered or the values changed.
*
* @public
*/
@XEmit('ExtraParamsProvided', { immediate: false, deep: true })
@Prop({ required: true })
public values!: Dictionary<unknown>;
export default defineComponent({
name: 'ExtraParams',
xModule: extraParamsXModule.name,
props: {
values: {
type: Object as PropType<Dictionary<unknown>>,
required: true
}
},
setup(props) {
const { params } = useState('extraParams', ['params']);
const $x = use$x();
/**
* State extra params. Used to override the initial extra params.
*/
@State('extraParams', 'params')
public storeExtraParams!: Dictionary<unknown>;
$x.emit('ExtraParamsInitialized', { ...props.values });
$x.emit('ExtraParamsProvided', { ...props.values, ...params.value });
// eslint-disable-next-line @typescript-eslint/no-empty-function
render(): void {}
}
watch(
() => props.values,
values => {
$x.emit('ExtraParamsProvided', { ...values });
},
{ deep: true }
);
// eslint-disable-next-line @typescript-eslint/no-empty-function
return () => {};
}
});
</script>

<docs lang="mdx">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,87 +4,59 @@

<script lang="ts">
import { forEach, Dictionary } from '@empathyco/x-utils';
import Vue from 'vue';
import { Component, Inject, Prop, Watch } from 'vue-property-decorator';
import { xComponentMixin } from '../../../components/x-component.mixin';
import { defineComponent, inject, PropType, ref, watch } from 'vue';
import { SnippetConfig } from '../../../x-installer/api/api.types';
import { extraParamsXModule } from '../x-module';
import ExtraParams from './extra-params.vue';
/**
* Extracts the extra parameters from the {@link SnippetConfig} and syncs it with the request
* objects of every x-module.
*
* @public
*/
@Component({
components: { ExtraParams },
mixins: [xComponentMixin(extraParamsXModule)]
})
export default class SnippetConfigExtraParams extends Vue {
/**
* It injects {@link SnippetConfig} provided by an ancestor as snippetConfig.
*
* @internal
*/
@Inject('snippetConfig')
public snippetConfig!: SnippetConfig;
/**
* A Dictionary where the keys are the extra param names and its values.
*
* @public
*/
@Prop()
protected values?: Dictionary<unknown>;
/**
* Custom object containing the extra params from the snippet config and the values prop.
*
* @remarks This object keeps manually the desired snippet config properties to avoid
* unnecessary re-renders.
*
* @returns A dictionary with the extra params.
*
* @internal
*/
protected extraParams: Dictionary<unknown> = {};
export default defineComponent({
name: 'SnippetConfigExtraParams',
xModule: extraParamsXModule.name,
components: {
ExtraParams
},
props: {
values: {
type: Object as PropType<Dictionary<unknown>>
},
excludedExtraParams: {
type: Array as PropType<Array<keyof SnippetConfig>>,
default: (): Array<keyof SnippetConfig> => [
'callbacks',
'productId',
'uiLang',
'consent',
'documentDirection',
'filters',
'isSpa',
'queriesPreview'
]
}
},
setup(props) {
const snippetConfig = inject('snippetConfig') as SnippetConfig;
const extraParams = ref({});
/**
* Updates the extraParams object when the snippet config or the values prop changes.
*
* @internal
*/
@Watch('snippetConfig', { deep: true, immediate: true })
@Watch('values', { deep: true, immediate: true })
syncExtraParams(): void {
forEach({ ...this.values, ...this.snippetConfig }, (name, value) => {
if (!this.excludedExtraParams.includes(name)) {
this.$set(this.extraParams, name, value);
watch(
[() => snippetConfig, () => props.values],
() => {
forEach({ ...props.values, ...snippetConfig }, (name, value) => {
if (!props.excludedExtraParams.includes(name)) {
extraParams.value = { ...extraParams.value, [name]: value };
}
});
},
{
deep: true,
immediate: true
}
});
}
);
/**
* Collection of properties from the snippet config to exclude from the
* extra params object.
*
* @public
*/
@Prop({
default: (): Array<keyof SnippetConfig> => [
'callbacks',
'productId',
'uiLang',
'consent',
'documentDirection',
'filters',
'isSpa',
'queriesPreview'
]
})
protected excludedExtraParams!: Array<keyof SnippetConfig>;
}
return {
extraParams
};
}
});
</script>

<docs lang="mdx">
Expand Down
3 changes: 3 additions & 0 deletions packages/x-components/src/x-modules/extra-params/x-module.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { XModule } from '../x-modules.types';
import { XPlugin } from '../../plugins/index';
import { extraParamsEmitters } from './store/emitters';
import { extraParamsXStoreModule } from './store/module';
import { ExtraParamsXStoreModule } from './store/types';
Expand All @@ -23,3 +24,5 @@ export const extraParamsXModule: ExtraParamsXModule = {
storeEmitters: extraParamsEmitters,
wiring: extraParamsWiring
};

XPlugin.registerXModule(extraParamsXModule);

0 comments on commit d869f18

Please sign in to comment.