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: Use XControls in NextQueries and Layout #360

Merged
merged 15 commits into from
Nov 13, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion public/snippet-script.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ window.initX = {
{
query: 'dress',
title: 'Autumn dresses by Marni',
filters: ['brand:marni', 'collection:autumn - 2022']
filters: ['brand:marni', 'categoryIds:12fad53d7']
},
{
query: 'belted legging',
Expand Down
5 changes: 0 additions & 5 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,6 @@
return this.snippetConfig.queriesPreview;
}

@XProvide('experienceControls')
public get experienceControls(): QueryPreviewInfo[] | undefined {
return this.$store.state.x.experienceControls.controls;
}

@Watch('snippetConfig.uiLang')
syncLang(uiLang: string): void {
this.$setLocale(uiLang);
Expand Down
6 changes: 3 additions & 3 deletions src/adapter/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ import {
recommendationsRequestSchema,
resultSchema,
semanticQueriesRequestSchema,
experienceControlsResponseSchema,
PlatformExperienceControlsResponse
experienceControlsResponseSchema
} from '@empathyco/x-adapter-platform';
import {
ExperienceControlsResponse,
Expand Down Expand Up @@ -63,9 +62,10 @@ semanticQueriesRequestSchema.$override<

// eslint-disable-next-line @typescript-eslint/no-unsafe-call
experienceControlsResponseSchema.$override<
PlatformExperienceControlsResponse,
Partial<ExperienceControlsResponse>,
Partial<ExperienceControlsResponse>
>({
controls: ({ controls }) => controls,
events: {
SemanticQueriesConfigProvided: {
maxItemsToRequest: 'controls.semanticQueries.numberOfCarousels',
Expand Down
9 changes: 8 additions & 1 deletion src/components/column-picker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
Grid4ColIcon
} from '@empathyco/x-components';
import { useDevice } from '../composables/use-device.composable';
import { useExperienceControls } from '../composables/use-experience-controls.composable';

export default defineComponent({
components: {
Expand All @@ -34,8 +35,14 @@
},
setup() {
const { isMobile } = useDevice();
const { getControlFromPath } = useExperienceControls();

const columns = computed(() =>
isMobile.value ? [2, 1] : getControlFromPath('layout.columnSelector', [4, 2])
);

return {
values: computed(() => (isMobile.value ? [2, 1] : [4, 2])),
values: columns,
icons: { 1: 'Grid1ColIcon', 2: 'Grid2ColIcon', 4: 'Grid4ColIcon' }
};
}
Expand Down
16 changes: 4 additions & 12 deletions src/components/search/custom-semantic-queries.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@

<script lang="ts">
import { ArrowRightIcon } from '@empathyco/x-components';
import { computed, defineComponent, inject } from 'vue';
import { defineComponent } from 'vue';
import { SemanticQueries, SemanticQuery } from '@empathyco/x-components/semantic-queries';
import { QueryPreviewList, useQueriesPreview } from '@empathyco/x-components/queries-preview';
import { Dictionary } from '@empathyco/x-utils';
import CustomSlidingPanel from '../custom-sliding-panel.vue';
import Result from '../results/result.vue';
import { useExperienceControls } from '../../composables/use-experience-controls.composable';
import DisplayClickProvider from './display-click-provider.vue';

export default defineComponent({
Expand All @@ -61,19 +61,11 @@
},
setup() {
const { isAnyQueryLoadedInPreview } = useQueriesPreview();

const experienceControls = inject<Dictionary>('experienceControls', {});

const resultsPerCarousel = computed(() => {
const resultsPerCarousel: number =
experienceControls.value?.controls?.semanticQueries?.resultsPerCarousels;

return resultsPerCarousel ?? undefined;
});
const { getControlFromPath } = useExperienceControls();

return {
isAnyQueryLoadedInPreview,
resultsPerCarousel
resultsPerCarousel: getControlFromPath('semanticQueries.resultsPerCarousels')
};
}
});
Expand Down
11 changes: 9 additions & 2 deletions src/components/search/results/results.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<NextQueriesList
:offset="24"
:frequency="48"
:maxNextQueriesPerGroup="1"
:maxNextQueriesPerGroup="maxNextQueriesPerGroup"
:showOnlyAfterOffset="$x.partialResults.length > 0"
>
<BaseVariableColumnGrid
Expand Down Expand Up @@ -55,6 +55,7 @@
import { NextQueriesList } from '@empathyco/x-components/next-queries';
import { useDevice } from '../../../composables/use-device.composable';
import Result from '../../results/result.vue';
import { useExperienceControls } from '../../../composables/use-experience-controls.composable';
import NextQueryPreview from './custom-next-query-preview.vue';

export default defineComponent({
Expand All @@ -75,7 +76,13 @@
},
setup() {
const { isMobile } = useDevice();
return { staggeredFadeAndSlide: StaggeredFadeAndSlide, columns: isMobile.value ? 2 : 4 };
const { getControlFromPath } = useExperienceControls();

return {
staggeredFadeAndSlide: StaggeredFadeAndSlide,
columns: isMobile.value ? 2 : 4,
maxNextQueriesPerGroup: getControlFromPath('nextQueries.maxItems', 1)
};
}
});
</script>
Expand Down
30 changes: 30 additions & 0 deletions src/composables/use-experience-controls.composable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { computed, ComputedRef } from 'vue';
import { getSafePropertyChain } from '@empathyco/x-utils';
import { ExperienceControlsState } from '@empathyco/x-components/experience-controls';
import { useStore } from './use-store.composable';

/**
* Given a controls' object property chain, gets the experience controls values from the response.
* A defaultValue can be set as a safeguard in case the controls response was empty.
*
* @returns An object containing the function to search for a configuration
* and set the experience controls property value.
*/
export const useExperienceControls = (): {
getControlFromPath: <SomeType>(path: string, defaultValue?: SomeType) => ComputedRef<SomeType>;
} => {
const experienceControls = (useStore('experienceControls') as ExperienceControlsState).controls;

const getControlFromPath = <SomeType>(
path: string,
defaultValue?: SomeType
): ComputedRef<SomeType> => {
return computed(() => {
return getSafePropertyChain(experienceControls, path, defaultValue) as SomeType;
});
};

return {
getControlFromPath
};
};
16 changes: 16 additions & 0 deletions src/composables/use-store.composable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// TODO: Change when useStore composable is added in x-components
import { getCurrentInstance } from 'vue';
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { RootXStoreState, StatusState, XModuleName, XModulesTree } from '@empathyco/x-components';

/**
* Provides access to the global store object or to the specific store module if it's provided.
*
* @param storeModule - The {@link XModuleName}.
* @returns A state object.
*/
export function useStore(storeModule?: keyof XModulesTree): RootXStoreState | StatusState {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a TODO to change when we add the useStore composable in x

return storeModule
? getCurrentInstance()!.proxy.$root.$store.state.x[storeModule]
: getCurrentInstance()!.proxy.$root.$store.state.x;
}
Loading