Skip to content

Commit

Permalink
Merge pull request #1483 from empathyco/feat/EMP-4142-migrate-base-su…
Browse files Browse the repository at this point in the history
…ggestions-to-composition-api

Feat: Migrate `base-suggestions` to composition api
  • Loading branch information
andreadlgdo authored May 29, 2024
2 parents 1fa8887 + 01b6d9c commit 49153f1
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 128 deletions.
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 @@ -7,3 +7,4 @@ export { default as TestBaseEventButton } from './test-base-event-button.vue';
export { default as TestBaseVariableColumnGrid } from './test-base-variable-column-grid.vue';
export { default as TestSlidingPanel } from './test-sliding-panel.vue';
export { default as TestUseLayouts } from './test-use-layouts.vue';
export { default as TestBaseSuggestions } from './suggestions/test-base-suggestions.vue';
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<template>
<BaseSuggestions :suggestions="suggestions">
<template #default="{ suggestion }">
<span>{{ suggestion.query }}</span>
</template>
</BaseSuggestions>
</template>

<script setup>
import BaseSuggestions from '../../../../x-components/src/components/suggestions/base-suggestions.vue';
import { getQuerySuggestionsStub } from '../../../../x-components/src/__stubs__';
const suggestions = getQuerySuggestionsStub('chip', 5);
</script>

<style scoped></style>
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 @@ -21,7 +21,8 @@ import {
TestBaseVariableColumnGrid,
TestEmpathize,
TestUseLayouts,
TestSlidingPanel
TestSlidingPanel,
TestBaseSuggestions
} from './';

const routes = [
Expand Down Expand Up @@ -134,6 +135,11 @@ const routes = [
path: '/test-use-layouts',
name: 'TestUseLayouts',
component: TestUseLayouts
},
{
path: '/base-suggestions',
name: 'BaseSuggestions',
component: TestBaseSuggestions
}
];

Expand Down
255 changes: 128 additions & 127 deletions packages/x-components/src/components/suggestions/base-suggestions.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,148 +19,149 @@
</template>

<script lang="ts">
import Vue from 'vue';
import { Component, Mixins, Prop } from 'vue-property-decorator';
import { Suggestion, Facet, Filter } from '@empathyco/x-types';
import { computed, defineComponent, PropType } from 'vue';
import { Suggestion, Facet } from '@empathyco/x-types';
import { isArrayEmpty } from '../../utils/array';
import { dynamicPropsMixin } from '../dynamic-props.mixin';
import { AnimationProp } from '../../types';
/**
* Paints a list of suggestions passed in by prop. Requires a component for a single suggestion
* in the default slot for working.
*
* @public
*/
@Component
export default class BaseSuggestions extends Mixins(dynamicPropsMixin(['suggestionItemClass'])) {
/**
* The list of suggestions to render.
*
* @public
*/
@Prop({ required: true })
protected suggestions!: Suggestion[];
/**
* Animation component that will be used to animate the suggestion.
*
* @public
*/
@Prop({ default: 'ul' })
protected animation!: Vue | string;
/**
* Number of suggestions to be rendered.
*
* @public
*/
@Prop()
protected maxItemsToRender?: number;
/**
* Boolean value to indicate if the facets should be rendered.
*
* @public
*/
@Prop({ default: false, type: Boolean })
protected showFacets!: boolean;
/**
* When {@link BaseSuggestions.showFacets} is true, it indicates if the suggestion without
* filter should be rendered.
*
* @public
*/
@Prop({ default: false, type: Boolean })
protected showPlainSuggestion!: boolean;
export default defineComponent({
name: 'BaseSuggestions',
props: {
/**
* The list of suggestions to render.
*
* @public
*/
suggestions: {
type: Array as PropType<Suggestion[]>,
required: true
},
/**
* Animation component that will be used to animate the suggestion.
*
* @public
*/
animation: {
type: AnimationProp,
default: 'ul'
},
/**
* Number of suggestions to be rendered.
*
* @public
*/
maxItemsToRender: Number,
/**
* Boolean value to indicate if the facets should be rendered.
*
* @public
*/
showFacets: {
type: Boolean,
default: false
},
/**
* When `showFacets` property of `BaseSuggestions` component is true, it indicates if the suggestion without
* filter should be rendered.
*
* @public
*/
showPlainSuggestion: {
type: Boolean,
default: false
},
/** Class inherited by content element. */
suggestionItemClass: String
},
setup: function (props) {
/**
* Creates a suggestion for each one of the filter inside each facet.
*
* @param suggestion - Suggestion to expand.
* @returns A list of suggestions, each one with a single filter.
*
* @internal
*/
const expandSuggestionFilters = (suggestion: Suggestion): Suggestion[] => {
return (
suggestion.facets?.flatMap(facet =>
facet.filters.map(filter => ({
...suggestion,
facets: [{ ...facet, filters: [filter] }]
}))
) ?? []
);
};
/**
* An array with the unique keys for each suggestion. Required by the `v-for` loop.
*
* @returns An array with the unique keys of the suggestions.
* @internal
*/
protected get suggestionsKeys(): string[] {
return this.suggestionsToRender.map(suggestion =>
isArrayEmpty(suggestion.facets)
? suggestion.query
: `${suggestion.query}-in-${this.getFacetsKey(suggestion.facets)}`
/**
* Creates a list of suggestions to render based on the configuration of this component.
*
* @returns - The list of suggestions to be rendered by this component.
*
* @internal
*/
const suggestionsToRender = computed(() =>
props.suggestions
.flatMap(suggestion =>
props.showFacets && suggestion.facets?.length
? props.showPlainSuggestion
? [{ ...suggestion, facets: [] }, ...expandSuggestionFilters(suggestion)]
: expandSuggestionFilters(suggestion)
: { ...suggestion, facets: [] }
)
.slice(0, props.maxItemsToRender)
);
}
/**
* Generates a string from the given facets.
*
* @param facets - The list of facets to reduce to a string.
* @returns - A string representing the list of facets.
* @internal
*/
protected getFacetsKey(facets: Facet[]): string {
// Component methods are bound by Vue:
// eslint-disable-next-line @typescript-eslint/unbound-method
return facets.map(this.getFacetKey).join('&');
}
/**
* Generates a string from the given facet.
*
* @param facet - The facet to reduce to a string.
* @returns - A string representing the facet.
* @internal
*/
protected getFacetKey(facet: Facet): string {
return facet.filters.map(filter => filter.id).join('&');
}
/**
* Creates a list of suggestions to render based on the configuration of this component.
*
* @returns - The list of suggestions to be rendered by this component.
*
* @internal
*/
protected get suggestionsToRender(): Suggestion[] {
return this.suggestions
.flatMap(suggestion =>
this.showFacets && suggestion.facets?.length
? this.showPlainSuggestion
? [{ ...suggestion, facets: [] }, ...this.expandSuggestionFilters(suggestion)]
: this.expandSuggestionFilters(suggestion)
: { ...suggestion, facets: [] }
/**
* Generates a string from the given facet.
*
* @param facet - The facet to reduce to a string.
* @returns - A string representing the facet.
* @internal
*/
const getFacetKey = (facet: Facet) => facet.filters.map(filter => filter.id).join('&');
/**
* Generates a string from the given facets.
*
* @param facets - The list of facets to reduce to a string.
* @returns - A string representing the list of facets.
* @internal
*/
const getFacetsKey = (facets: Facet[]) => facets.map(getFacetKey).join('&');
/**
* An array with the unique keys for each suggestion. Required by the `v-for` loop.
*
* @returns An array with the unique keys of the suggestions.
* @internal
*/
const suggestionsKeys = computed(() =>
suggestionsToRender.value.map(suggestion =>
isArrayEmpty(suggestion.facets)
? suggestion.query
: `${suggestion.query}-in-${getFacetsKey(suggestion.facets)}`
)
.slice(0, this.maxItemsToRender);
}
/**
* Creates a suggestion for each one of the filter inside each facet.
*
* @param suggestion - Suggestion to expand.
* @returns A list of suggestions, each one with a single filter.
*
* @internal
*/
protected expandSuggestionFilters(suggestion: Suggestion): Suggestion[] {
return (
suggestion.facets?.flatMap(facet =>
facet.filters.map(filter => ({
...suggestion,
facets: [{ ...facet, filters: [filter] }]
}))
) ?? []
);
}
/**
* Returns the filter contained by the suggestion.
*
* @param suggestion - Suggestion containing the filter.
* @returns The suggestion filter.
* @internal
*/
protected getSuggestionFilter(suggestion: Suggestion): Filter | undefined {
return suggestion.facets?.[0]?.filters[0];
/**
* Returns the filter contained by the suggestion.
*
* @param suggestion - Suggestion containing the filter.
* @returns The suggestion filter.
* @internal
*/
const getSuggestionFilter = (suggestion: Suggestion) => suggestion.facets?.[0]?.filters[0];
return { suggestionsToRender, suggestionsKeys, getSuggestionFilter };
}
}
});
</script>

<style lang="scss" scoped>
Expand Down

0 comments on commit 49153f1

Please sign in to comment.