Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Migrate facets provider component to use Composition API #1523

Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
<script lang="ts">
import { Facet, Filter, isHierarchicalFacet } from '@empathyco/x-types';
import Vue from 'vue';
import { Component, Prop, Watch } from 'vue-property-decorator';
import { XOn } from '../../../../components';
import { xComponentMixin } from '../../../../components/x-component.mixin';
import { computed, defineComponent, h, PropType, Ref, ref, watch } from 'vue';
import { clone } from '../../../../utils';
import { areFiltersDifferent } from '../../../../utils/filters';
import { FacetsGroup } from '../../service/types';
import { GroupId } from '../../store/types';
import { flatHierarchicalFilters } from '../../utils';
import { facetsXModule } from '../../x-module';
import { use$x } from '../../../../composables/use-$x';

/**
* This component allows to provide facets by prop, to add them to the state of the
Expand All @@ -19,97 +16,107 @@
*
* @public
*/
@Component({
mixins: [xComponentMixin(facetsXModule)]
})
export default class FacetsProvider extends Vue {
/**
* An facet group identifier to distinguish the provided facets from other facets like the
* `Search X-Module` facets.
*
* @public
*/
@Prop({ default: 'provided-facets' })
public groupId!: GroupId;

/**
* The facets to provide to the `Facets X-Module` state. They have to include the
* {@link @empathyco/x-types#Filter}.
*
* @internal
*/
@Prop({ required: true })
public facets!: Facet[];

/**
* Temporarily stores the selected filters from the {@link FacetsProvider.facets} prop.
* This is necessary to handle the {@link FacetsXEvents.UserChangedSelectedFilters} event.
*
* @internal
*/
protected selectedFilters: Filter[] | null = null;

/**
* A computed property to group the facets and the groupId. This is used by the watcher.
*
* @returns The FacetGroup with the facets and the group id.
*
* @internal
*/
protected get facetsGroup(): FacetsGroup {
return { id: this.groupId, facets: this.facets };
}

/**
* Emits the {@link FacetsXEvents.UserChangedSelectedFilters} event when the user changes
* the selected filters.
*
* @param selectedFilters - The new list of selected filters.
* @internal
*/
@XOn('SelectedFiltersChanged')
emitSelectedFiltersChanged(selectedFilters: Filter[]): void {
if (
this.selectedFilters === null ||
areFiltersDifferent(this.selectedFilters, selectedFilters)
) {
this.$x.emit('UserChangedSelectedFilters', selectedFilters);
export default defineComponent({
name: 'FacetsProvider',
xModule: facetsXModule.name,
lauramargar marked this conversation as resolved.
Show resolved Hide resolved
props: {
/**
* An facet group identifier to distinguish the provided facets from other facets like the
* `Search X-Module` facets.
*
* @public
*/
groupId: {
type: String as PropType<GroupId>,
default: 'provided-facets'
},
/**
* The facets to provide to the `Facets X-Module` state. They have to include the
* {@link @empathyco/x-types#Filter}.
*
* @internal
*/
facets: {
type: Array as PropType<Facet[]>,
required: true
}
this.selectedFilters = null;
}
},
setup: function (props) {
const $x = use$x();

/**
* Temporarily stores the selected filters from the {@link FacetsProvider.facets} prop.
* This is necessary to handle the {@link FacetsXEvents.UserChangedSelectedFilters} event.
*
* @internal
*/
const selectedFilters: Ref<Filter[] | null> = ref(null);

/**
* A computed property to group the facets and the groupId. This is used by the watcher.
*
* @returns The FacetGroup with the facets and the group id.
*
* @internal
*/
const facetsGroup = computed(() => {
return { id: props.groupId, facets: props.facets };
andreadlgdo marked this conversation as resolved.
Show resolved Hide resolved
});

/**
* Emits the {@link FacetsXEvents.UserChangedSelectedFilters} event when the user changes
* the selected filters.
*
* @param selectedFilters - The new list of selected filters.
* @internal
*/
$x.on('SelectedFiltersChanged', false).subscribe((selectedFiltersParams: Filter[]) => {
if (
selectedFilters.value === null ||
areFiltersDifferent(selectedFilters.value, selectedFiltersParams)
) {
$x.emit('UserChangedSelectedFilters', selectedFiltersParams);
}
selectedFilters.value = null;
});

/**
* Extracts the selected filters from the facets and stores them in the
* {@link FacetsProvider.selectedFilters} property.
*
* @param facets - The facets from whom extract the selected filters.
* @internal
*/
const extractSelectedFilters = (facets: Facet[]) => {
selectedFilters.value = facets
.flatMap(facet =>
isHierarchicalFacet(facet) ? flatHierarchicalFilters(facet.filters) : facet.filters
)
.filter(filter => filter.selected);
};

/**
* Emits the {@link FacetsXEvents.FacetsGroupProvided} event with the
* {@link FacetsProvider.facetsGroup} as payload. It also extracts and saves the selected
* filters.
*/
@Watch('facetsGroup', { immediate: true })
provideFacets(): void {
if (this.facetsGroup.facets) {
const facetsGroupClone = clone(this.facetsGroup);
this.$x.emit('FacetsGroupProvided', facetsGroupClone);
this.extractSelectedFilters(this.facets);
}
}
/**
* Emits the {@link FacetsXEvents.FacetsGroupProvided} event with the
* {@link FacetsProvider.facetsGroup} as payload. It also extracts and saves the selected
* filters.
*/
watch(
() => facetsGroup.value,
() => {
if (facetsGroup.value.facets) {
const facetsGroupClone = clone(facetsGroup.value);
$x.emit('FacetsGroupProvided', facetsGroupClone);
extractSelectedFilters(props.facets);
}
},
{ immediate: true }
);

/**
* Extracts the selected filters from the facets and stores them in the
* {@link FacetsProvider.selectedFilters} property.
*
* @param facets - The facets from whom extract the selected filters.
* @internal
*/
protected extractSelectedFilters(facets: Facet[]): void {
this.selectedFilters = facets
.flatMap(facet =>
isHierarchicalFacet(facet) ? flatHierarchicalFilters(facet.filters) : facet.filters
)
.filter(filter => filter.selected);
return () => {
return h();
};
}

// eslint-disable-next-line @typescript-eslint/no-empty-function
render(): void {}
}
});
</script>

<style lang="scss" scoped>
Expand Down
Loading