Skip to content

Commit

Permalink
feat: migrate RTs module to composition API (#1498)
Browse files Browse the repository at this point in the history
Co-authored-by: Jose A. Cabaneros <[email protected]>
Co-authored-by: Diego Pascual <[email protected]>
Co-authored-by: Víctor CG <[email protected]>
  • Loading branch information
4 people authored Jun 12, 2024
1 parent 8ea9a9c commit 22c5325
Show file tree
Hide file tree
Showing 10 changed files with 3,157 additions and 8,515 deletions.
7 changes: 6 additions & 1 deletion packages/_vue3-migration-test/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ 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 App from './App.vue';
import router from './router';
Expand All @@ -28,11 +29,15 @@ if (VUE_COMPAT_MODE === 2) {
}

const adapter = {
relatedTags: () =>
new Promise(resolve => {
resolve({ relatedTags: getRelatedTagsStub(10) });
}),
querySuggestions: (request: QuerySuggestionsRequest) =>
new Promise(resolve => {
resolve({ suggestions: getQuerySuggestionsStub(request.query, 5) });
})
} as XComponentsAdapter;
} as unknown as XComponentsAdapter;

const store = createStore({});

Expand Down
6 changes: 6 additions & 0 deletions packages/_vue3-migration-test/src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
TestBaseResultImages,
TestBasePanel,
TestBaseKeyboardNavigation,
TestRelatedTags,
TestPartialResultsList,
TestBaseEventsModal,
TestBaseIdModal,
Expand Down Expand Up @@ -181,6 +182,11 @@ const routes = [
name: 'TestBaseKeyboardNavigation',
component: TestBaseKeyboardNavigation
},
{
path: '/related-tags',
name: 'RelatedTags',
component: TestRelatedTags
},
{
path: '/partial-results-list',
name: 'PartialResultsList',
Expand Down
1 change: 1 addition & 0 deletions packages/_vue3-migration-test/src/x-modules/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ export * from './search';
export * from './search-box';
export { default as TestElementsList } from './test-elements-list.vue';
export * from './scroll';
export * from './related-tags';
export * from './history-queries';
export * from './query-suggestions';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as TestRelatedTags } from './test-related-tags.vue';
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<template>
<span style="display: block">
Query:
<b>{{ query }}</b>
</span>
<SearchInput />
<RelatedTags />
</template>

<script setup>
import SearchInput from '../../../../x-components/src/x-modules/search-box/components/search-input.vue';
import RelatedTags from '../../../../x-components/src/x-modules/related-tags/components/related-tags.vue';
import { useGetter } from '../../../../x-components/src/composables/use-getter';
const { query } = useGetter('relatedTags', ['query']);
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ describe('testing plugin alias', () => {
popularSearches: undefined,
querySuggestions: 'initial', // It is already registered by the `querySuggestionsXModule` import itself
recommendations: undefined,
relatedTags: undefined,
relatedTags: 'initial', // It is already registered by the `relatedTagsXModule` import itself
search: undefined
},
device: null,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<template>
<button
ref="buttonEl"
@click="clickRelatedTag"
class="x-tag x-related-tag"
data-test="related-tag"
Expand All @@ -16,14 +17,14 @@
</template>

<script lang="ts">
import Vue from 'vue';
import { Component, Prop } from 'vue-property-decorator';
import { computed, ComputedRef, defineComponent, PropType, ref } from 'vue';
import { RelatedTag as RelatedTagModel } from '@empathyco/x-types';
import { State } from '../../../components/decorators/store.decorators';
import { xComponentMixin } from '../../../components/x-component.mixin';
import { Dictionary } from '@empathyco/x-utils';
import { VueCSSClasses } from '../../../utils/types';
import { WireMetadata } from '../../../wiring/wiring.types';
import { relatedTagsXModule } from '../x-module';
import { use$x } from '../../../composables/use-$x';
import { useState } from '../../../composables/use-state';
/**
* This component renders a related tag for a query. A related tag is a descriptive keyword
Expand All @@ -32,119 +33,135 @@
*
* @public
*/
@Component({
mixins: [xComponentMixin(relatedTagsXModule)]
})
export default class RelatedTag extends Vue {
/**
* Indicates if the curated related tag should be highlighted.
*
* @public
*/
@Prop({ default: false, type: Boolean })
protected highlightCurated!: boolean;
/**
* The related tag model data.
*
* @public
*/
@Prop({ required: true })
protected relatedTag!: RelatedTagModel;
/**
* The selected related tags.
*
* @internal
*/
@State('relatedTags', 'selectedRelatedTags')
public selectedRelatedTags!: RelatedTagModel[];
/**
* Blurs the related tag if it is selected.
*
* @public
*/
protected blurRelatedTag(): void {
if (this.isSelected) {
(this.$el as HTMLElement).blur();
export default defineComponent({
name: 'RelatedTag',
xModule: relatedTagsXModule.name,
props: {
/**
* Indicates if the curated related tag should be highlighted.
*
* @public
*/
highlightCurated: {
type: Boolean,
default: false
},
/**
* The related tag model data.
*
* @public
*/
relatedTag: {
type: Object as PropType<RelatedTagModel>,
required: true
}
}
},
setup(props) {
const $x = use$x();
const buttonEl = ref<HTMLElement | undefined>();
/**
* The selected related tags.
*
* @internal
*/
const { selectedRelatedTags }: Dictionary<ComputedRef<RelatedTagModel[]>> = useState(
'relatedTags',
['selectedRelatedTags']
);
/**
* Handles the click on the button.
*
* @public
*/
protected clickRelatedTag(): void {
this.emitEvents();
this.blurRelatedTag();
}
/**
* Check if the related tag is selected or not.
*
* @returns If the related tag is selected.
*
* @internal
*/
const isSelected = computed(() => selectedRelatedTags.value.includes(props.relatedTag));
/**
* Blurs the related tag if it is selected.
*
* @public
*/
const blurRelatedTag = () => {
if (isSelected.value) {
buttonEl.value?.blur();
}
};
/**
* Generates the {@link WireMetadata} object omitting the moduleName.
*
* @returns The {@link WireMetadata} object omitting the moduleName.
* @internal
*/
protected createEventMetadata(): Omit<WireMetadata, 'moduleName'> {
return {
target: this.$el as HTMLElement,
/**
* Generates the {@link WireMetadata} object omitting the moduleName.
*
* @returns The {@link WireMetadata} object omitting the moduleName.
* @internal
*/
const createEventMetadata = (): Omit<WireMetadata, 'moduleName'> => ({
target: buttonEl.value as HTMLElement,
feature: 'related_tag'
});
/**
* Emits events when the button is clicked.
*
* @public
*/
const emitEvents = () => {
// We have to emit this events first to avoid the UserPickedARelatedTag wires to change the
// isSelected value before emitting this selection events.
$x.emit(
isSelected.value ? 'UserDeselectedARelatedTag' : 'UserSelectedARelatedTag',
props.relatedTag,
createEventMetadata()
);
$x.emit('UserPickedARelatedTag', props.relatedTag, createEventMetadata());
};
}
/**
* Emits events when the button is clicked.
*
* @public
*/
protected emitEvents(): void {
// We have to emit this events first to avoid the UserPickedARelatedTag wires to change the
// isSelected value before emitting this selection events.
this.$x.emit(
this.isSelected ? 'UserDeselectedARelatedTag' : 'UserSelectedARelatedTag',
this.relatedTag,
this.createEventMetadata()
);
this.$x.emit('UserPickedARelatedTag', this.relatedTag, this.createEventMetadata());
}
/**
* Handles the click on the button.
*
* @public
*/
const clickRelatedTag = () => {
emitEvents();
blurRelatedTag();
};
/**
* Check if the related tag is selected or not.
*
* @returns If the related tag is selected.
*
* @internal
*/
protected get isSelected(): boolean {
return this.selectedRelatedTags.includes(this.relatedTag);
}
/**
* Check if the related tag is curated and should be highlighted.
*
* @returns True if the related tag is curated and should be highlighted.
*
* @internal
*/
const shouldHighlightCurated = computed(
() => props.highlightCurated && (props.relatedTag.isCurated ?? false)
);
/**
* Check if the related tag is curated and should be highlighted.
*
* @returns True if the related tag is curated and should be highlighted.
*
* @internal
*/
protected get shouldHighlightCurated(): boolean {
return this.highlightCurated && (this.relatedTag.isCurated ?? false);
}
/**
* Adds the dynamic css classes to the component.
*
* @returns The class to be added to the component.
*
* @internal
*/
const dynamicClasses = computed(
(): VueCSSClasses => ({
'x-selected x-related-tag--is-selected': isSelected.value,
'x-related-tag--is-curated': shouldHighlightCurated.value
})
);
/**
* Adds the dynamic css classes to the component.
*
* @returns The class to be added to the component.
*
* @internal
*/
protected get dynamicClasses(): VueCSSClasses {
return {
'x-selected': this.isSelected,
'x-related-tag--is-selected': this.isSelected,
'x-related-tag--is-curated': this.shouldHighlightCurated
buttonEl,
dynamicClasses,
isSelected,
clickRelatedTag,
shouldHighlightCurated
};
}
}
});
</script>

<docs lang="mdx">
Expand Down
Loading

0 comments on commit 22c5325

Please sign in to comment.