Skip to content

Commit

Permalink
feat: Create useFacets composable and use it on ClearFilters component
Browse files Browse the repository at this point in the history
  • Loading branch information
alvarodE committed May 6, 2024
1 parent a97d4a5 commit 62bc848
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,55 +12,66 @@
</template>

<script lang="ts">
import Component from 'vue-class-component';
import { xComponentMixin } from '../../../components';
import { Facet } from '@empathyco/x-types';
import { computed, defineComponent, PropType } from 'vue';
import BaseEventButton from '../../../components/base-event-button.vue';
import { VueCSSClasses } from '../../../utils';
import { XEventsTypes } from '../../../wiring';
import { VueCSSClasses } from '../../../utils/types';
import { XEventsTypes } from '../../../wiring/events.types';
import { useFacets } from '../composables/use-facets.composable';
import { facetsXModule } from '../x-module';
import FacetsMixin from './facets.mixin';
/**
* Renders a simple button, emitting the needed events when clicked.
*
* @remarks It extends {@link FacetsMixin}.
*
* @public
*/
@Component({
export default defineComponent({
name: 'ClearFilters',
xModule: facetsXModule.name,
components: { BaseEventButton },
mixins: [xComponentMixin(facetsXModule)]
})
export default class ClearFilters extends FacetsMixin {
/**
* The events that will be emitted when the button clear filters is clicked.
*
* @returns The events to be emitted when the button clear filters is clicked.
* @internal
*/
protected get events(): Partial<XEventsTypes> {
return this.facetsIds
? {
UserClickedClearAllFilters: this.facetsIds
}
: {
UserClickedClearAllFilters: undefined
};
}
props: {
/** Array of facets ids used to get the selected filters for those facets. */
facetsIds: Array as PropType<Array<Facet['id']>>,
/** Flag to render the component even if there are no filters selected. */
alwaysVisible: Boolean
},
setup: function (props) {
const { selectedFilters, hasSelectedFilters, isVisible } = useFacets(props);
/**
* The events that will be emitted when the button clear filters is clicked.
*
* @returns The events to be emitted when the button clear filters is clicked.
*/
const events = computed<Partial<XEventsTypes>>(() =>
props.facetsIds
? {
UserClickedClearAllFilters: props.facetsIds
}
: {
UserClickedClearAllFilters: undefined
}
);
/**
* Dynamic CSS classes to apply to the component.
*
* @returns The dynamic CSS classes to apply to the component.
*/
const cssClasses = computed<VueCSSClasses>(() => ({
'x-clear-filters--has-not-selected-filters': !hasSelectedFilters.value,
'x-clear-filters--has-selected-filters': hasSelectedFilters.value
}));
/**
* Dynamic CSS classes to apply to the component.
*
* @returns The dynamic CSS classes to apply to the component.
* @internal
*/
protected get cssClasses(): VueCSSClasses {
return {
'x-clear-filters--has-not-selected-filters': !this.hasSelectedFilters,
'x-clear-filters--has-selected-filters': this.hasSelectedFilters
selectedFilters,
hasSelectedFilters,
isVisible,
events,
cssClasses
};
}
}
});
</script>

<docs lang="mdx">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './use-facets.composable';
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { Facet, Filter } from '@empathyco/x-types';
import { computed, ComputedRef } from 'vue';
import { useGetter } from '../../../composables/use-getter';
import { isArrayEmpty } from '../../../utils/array';
import { FiltersByFacet } from '../store/types';

/**
* Composable to share Facets logic.
*
* @param params - Composable params.
* @returns Composable.
*
* @public
*/
export function useFacets({
facetsIds,
alwaysVisible = false
}: {
/** Array of facets ids used to get the selected filters for those facets. */
facetsIds?: Array<Facet['id']>;
/** Flag to render the component even if there are no filters selected. */
alwaysVisible?: boolean;
}) {
const { selectedFiltersByFacet, selectedFilters: selectedFiltersGetter } = useGetter('facets', [
'selectedFiltersByFacet',
'selectedFilters'
]) as {
/** Dictionary of filters {@link FiltersByFacet} filtered by facet id. */
selectedFiltersByFacet: ComputedRef<FiltersByFacet>;
/** Get the selected filters from store. */
selectedFilters: ComputedRef<Filter[]>;
};

/**
* Get selected filters.
* If there are facets ids, get selected filters whose facet id match with some of facets ids.
* If there aren't facets ids, get selected filters.
*
* @returns Array of selected filters depends on there are facets ids or not.
*/
const selectedFilters = computed<Filter[]>(() => {
if (facetsIds) {
return (facetsIds as string[]).reduce(
(selectedFilters, facetId) => [
...selectedFilters,
...selectedFiltersByFacet.value[facetId]
],
[] as Filter[]
);
}

return selectedFiltersGetter.value;
});

/**
* Check if there are selected filters.
*
* @returns True or false depends on if there are selected filters.
*/
const hasSelectedFilters = computed<boolean>(() => !isArrayEmpty(selectedFilters.value));

/**
* Flag representing if the component should be visible/rendered or not.
*
* @returns True whenever alwaysVisible is true or has selected filters. False
* otherwise.
*/
const isVisible = computed<boolean>(() => alwaysVisible || hasSelectedFilters.value);

return {
selectedFiltersByFacet,
selectedFilters,
hasSelectedFilters,
isVisible
};
}
1 change: 1 addition & 0 deletions packages/x-components/src/x-modules/facets/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export * from './wiring';
export * from './service';
export * from './entities';
export * from './components';
export * from './composables';
export * from './events.types';
export * from './utils';
export { default as FacetsMixin } from './components/facets.mixin';

0 comments on commit 62bc848

Please sign in to comment.