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: implement related prompts #1639

Draft
wants to merge 8 commits into
base: vue3-update-rc
Choose a base branch
from
Draft
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { endpointAdapterFactory } from '@empathyco/x-adapter';
import { RelatedPromptsRequest, RelatedPromptsResponse } from '@empathyco/x-types';
import { relatedPromptsRequestMapper } from '../mappers/requests/related-prompts-request.mapper';
import { relatedPromptsResponseMapper } from '../mappers/responses/related-prompts-response.mapper';

/**
* This endpoint does not support pagination in the request.
*/
export const relatedPromptsEndpointAdapter = endpointAdapterFactory<
RelatedPromptsRequest,
RelatedPromptsResponse
>({
endpoint: 'https://api.staging.empathy.co/relatedprompts/fmj?',
requestMapper: relatedPromptsRequestMapper,
responseMapper: relatedPromptsResponseMapper
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { schemaMapperFactory } from '@empathyco/x-adapter';
import { RelatedPromptsRequest } from '@empathyco/x-types';

/**
* Default implementation for the RelatedPromptsRequestMapper.
*/
export const relatedPromptsRequestMapper = schemaMapperFactory<RelatedPromptsRequest, any>({
// randomize: () => true,
lang: () => 'en',
// scoreThreshold: () => 0.7,
query: 'query'
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import { PlatformRelatedTagsRequest } from '../../types/requests/related-tags-re

/**
* Default implementation for the RelatedTagsRequestMapper.
*
* @public
*/
export const relatedTagsRequestMapper = schemaMapperFactory<
RelatedTagsRequest,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { schemaMapperFactory } from '@empathyco/x-adapter';
import { RelatedPromptsResponse } from '@empathyco/x-types';

/**
* Default implementation for the RelatedPromptsResponseMapper.
*
* @public
*/
export const relatedPromptsResponseMapper = schemaMapperFactory<any, RelatedPromptsResponse>({
relatedPromptsProducts: response => response.data?.relatedprompts ?? []
});
2 changes: 2 additions & 0 deletions packages/x-adapter-platform/src/platform.adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { PlatformAdapter } from './types/platform-adapter.types';
import { popularSearchesEndpointAdapter } from './endpoint-adapters/popular-searches.endpoint-adapter';
import { recommendationsEndpointAdapter } from './endpoint-adapters/recommendations.endpoint-adapter';
import { nextQueriesEndpointAdapter } from './endpoint-adapters/next-queries.endpoint-adapter';
import { relatedPromptsEndpointAdapter } from './endpoint-adapters/related-prompts.endpoint-adapter';
import { relatedTagsEndpointAdapter } from './endpoint-adapters/related-tags.endpoint-adapter';
import { identifierResultsEndpointAdapter } from './endpoint-adapters/identifier-results.endpoint-adapter';
import { taggingEndpointAdapter } from './endpoint-adapters/tagging.endpoint-adapter';
Expand All @@ -23,6 +24,7 @@ export const platformAdapter: PlatformAdapter = {
recommendations: recommendationsEndpointAdapter,
nextQueries: nextQueriesEndpointAdapter,
querySuggestions: querySuggestionsEndpointAdapter,
relatedPrompts: relatedPromptsEndpointAdapter,
relatedTags: relatedTagsEndpointAdapter,
identifierResults: identifierResultsEndpointAdapter,
tagging: taggingEndpointAdapter,
Expand Down
1 change: 1 addition & 0 deletions packages/x-components/src/__tests__/adapter.dummy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export const XComponentsAdapterDummy: XComponentsAdapter = {
popularSearches: jest.fn(),
querySuggestions: jest.fn(),
recommendations: jest.fn(),
relatedPrompts: jest.fn(),
relatedTags: jest.fn(),
search: jest.fn(),
semanticQueries: jest.fn(),
Expand Down
5 changes: 4 additions & 1 deletion packages/x-components/src/__tests__/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import {
RelatedTagsResponse,
SearchResponse,
SemanticQueriesResponse,
ExperienceControlsResponse
ExperienceControlsResponse,
RelatedPromptsResponse
} from '@empathyco/x-types';
import { XPluginOptions } from '../plugins';
import { XPlugin } from '../plugins/x-plugin';
Expand Down Expand Up @@ -41,6 +42,7 @@ interface MockedAdapterFeatures {
popularSearches: PopularSearchesResponse;
querySuggestions: QuerySuggestionsResponse;
recommendations: RecommendationsResponse;
relatedPrompts: RelatedPromptsResponse;
relatedTags: RelatedTagsResponse;
search: SearchResponse;
semanticQueries: SemanticQueriesResponse;
Expand Down Expand Up @@ -156,6 +158,7 @@ export function getMockedAdapter(
popularSearches: getMockedAdapterFunction(responseFeatures?.popularSearches!),
querySuggestions: getMockedAdapterFunction(responseFeatures?.querySuggestions!),
recommendations: getMockedAdapterFunction(responseFeatures?.recommendations!),
relatedPrompts: getMockedAdapterFunction(responseFeatures?.relatedPrompts!),
relatedTags: getMockedAdapterFunction(responseFeatures?.relatedTags!),
search: getMockedAdapterFunction(responseFeatures?.search!),
semanticQueries: getMockedAdapterFunction(responseFeatures?.semanticQueries!),
Expand Down
1 change: 1 addition & 0 deletions packages/x-components/src/adapter/e2e-adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export const e2eAdapter: XComponentsAdapter = {
popularSearches: mockEndpointAdapter('popular-searches'),
querySuggestions: mockEndpointAdapter('query-suggestions'),
recommendations: mockEndpointAdapter('recommendations'),
relatedPrompts: mockEndpointAdapter('related-prompts'),
relatedTags: mockEndpointAdapter('related-tags'),
search: mockEndpointAdapter('search'),
semanticQueries: mockEndpointAdapter('semantic-queries'),
Expand Down
57 changes: 12 additions & 45 deletions packages/x-components/src/views/home/Home.vue
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@
>
<PromotedsList class="x-mot-promoteds-list">
<BannersList class="x-mot-banners-list">
<NextQueriesList
<RelatedPromptsList
:show-only-after-offset="controls.nextQueriesList.showOnlyAfterOffset"
class="x-mot-next-queries-list"
>
Expand All @@ -334,46 +334,11 @@
<template #promoted="{ item: promoted }">
<Promoted :promoted="promoted" />
</template>

<template #next-queries-group="{ item: { nextQueries } }">
<NextQueryPreview
:suggestion="nextQueries[0]"
:max-items-to-render="controls.nextQueriesPreview.maxItemsToRender"
#default="{ results }"
class="x-pt-24"
>
<h1 class="x-title2">Others clients have searched</h1>
<NextQuery
class="x-suggestion x-text1 x-text1-lg"
:suggestion="nextQueries[0]"
data-test="next-query-preview-name"
>
<span class="x-font-bold">{{ nextQueries[0].query }}</span>
</NextQuery>
<div class="x-mb-24">
<SlidingPanel :resetOnContentChange="false">
<div class="x-flex x-flex-row x-gap-8">
<Result
v-for="result in results"
:key="result.id"
:result="result"
style="max-width: 180px"
data-test="next-query-preview-result"
/>
</div>
</SlidingPanel>
</div>
<NextQuery
:suggestion="nextQueries[0]"
data-test="view-all-results"
class="x-button x-button-outlined x-rounded-full x-mx-auto x-mt-8 x-mb-24"
>
{{ 'View all results' }}
</NextQuery>
</NextQueryPreview>
<template #related-prompts-group="{ item: { relatedPrompts } }">
<pre>{{ relatedPrompts }}</pre>
</template>
</BaseVariableColumnGrid>
</NextQueriesList>
</RelatedPromptsList>
</BannersList>
</PromotedsList>
</ResultsList>
Expand Down Expand Up @@ -494,8 +459,8 @@
import SnippetCallbacks from '../../components/snippet-callbacks.vue';
import RenderlessExtraParams from '../../x-modules/extra-params/components/renderless-extra-param.vue';
import SnippetConfigExtraParams from '../../x-modules/extra-params/components/snippet-config-extra-params.vue';
import NextQueriesList from '../../x-modules/next-queries/components/next-queries-list.vue';
import NextQueryPreview from '../../x-modules/next-queries/components/next-query-preview.vue';
// import NextQueriesList from '../../x-modules/next-queries/components/next-queries-list.vue';
// import NextQueryPreview from '../../x-modules/next-queries/components/next-query-preview.vue';
import QueryPreviewList from '../../x-modules/queries-preview/components/query-preview-list.vue';
import Recommendations from '../../x-modules/recommendations/components/recommendations.vue';
import RelatedTags from '../../x-modules/related-tags/components/related-tags.vue';
Expand All @@ -522,14 +487,15 @@
import OpenMainModal from '../../components/modals/open-main-modal.vue';
import CloseMainModal from '../../components/modals/close-main-modal.vue';
import { adapterConfig } from '../adapter';
import NextQuery from '../../x-modules/next-queries/components/next-query.vue';
// import NextQuery from '../../x-modules/next-queries/components/next-query.vue';
import FallbackDisclaimer from '../../x-modules/search/components/fallback-disclaimer.vue';
import SemanticQueries from '../../x-modules/semantic-queries/components/semantic-queries.vue';
import SemanticQuery from '../../x-modules/semantic-queries/components/semantic-query.vue';
import { useQueriesPreview } from '../../x-modules/queries-preview/composables/use-queries-preview.composable';
import { QueryPreviewInfo } from '../../x-modules/queries-preview/store/types';
import QueryPreviewButton from '../../x-modules/queries-preview/components/query-preview-button.vue';
import DisplayEmitter from '../../components/display-emitter.vue';
import RelatedPromptsList from '../../x-modules/related-prompts/components/related-prompts-list.vue';
import Aside from './aside.vue';
import PredictiveLayer from './predictive-layer.vue';
import Result from './result.vue';
Expand Down Expand Up @@ -566,9 +532,10 @@
MainModal,
MainScrollItem,
MultiColumnMaxWidthLayout,
NextQueriesList,
NextQuery,
NextQueryPreview,
// NextQueriesList,
// NextQuery,
// NextQueryPreview,
RelatedPromptsList,
OpenMainModal,
PartialQueryButton,
PartialResultsList,
Expand Down
5 changes: 4 additions & 1 deletion packages/x-components/src/wiring/events.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { UrlXEvents } from '../x-modules/url/events.types';
import { XModuleName } from '../x-modules/x-modules.types';
import { SemanticQueriesXEvents } from '../x-modules/semantic-queries/events.types';
import { ExperienceControlsXEvents } from '../x-modules/experience-controls/events.types';
import { RelatedPromptsXEvents } from '../x-modules/related-prompts/events.types';
import { WireMetadata } from './wiring.types';
/* eslint-disable max-len */
/**.
Expand Down Expand Up @@ -51,6 +52,7 @@ import { WireMetadata } from './wiring.types';
* {@link https://github.com/empathyco/x/blob/main/packages/x-components/src/x-modules/search/events.types.ts | SearchXEvents}
* {@link https://github.com/empathyco/x/blob/main/packages/x-components/src/x-modules/tagging/events.types.ts | TaggingXEvents}
* {@link https://github.com/empathyco/x/blob/main/packages/x-components/src/x-modules/url/events.types.ts | UrlXEvents}
* {@link https://github.com/empathyco/x/blob/main/packages/x-components/src/x-modules/related-prompts/events.types.ts | UrlXEvents}
*
* @public
*/
Expand All @@ -73,7 +75,8 @@ export interface XEventsTypes
SemanticQueriesXEvents,
TaggingXEvents,
ExperienceControlsXEvents,
UrlXEvents {
UrlXEvents,
RelatedPromptsXEvents {
/**
* The provided number of columns of a grid has changed.
* Payload: the columns number.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default as RelatedPrompt } from './related-prompt.vue';
export { default as RelatedPromptsList } from './related-prompts-list.vue';
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<template>
<div class="x-flex x-flex-col x-gap-16 x-bg-neutral-10 x-p-24 x-pl-16 x-pr-0 desktop:x-px-24">
<div class="x-flex x-flex-col x-gap-16">
<h1 class="x-text1 x-text1-lg x-pr-16 x-font-main x-text-neutral-90 desktop:x-pr-0">
{{ relatedPrompt.suggestionText }}
</h1>
<SlidingPanel>
<div class="x-flex x-gap-8 x-pr-8">
<button
v-for="(nextQuery, index) in relatedPrompt.nextQueries"
:key="index"
@click="onClick(nextQuery)"
class="x-button x-button-lead x-button-sm x-button-outlined x-rounded-sm x-border-lead-50 x-text-neutral-75 hover:x-text-neutral-0 selected:x-text-neutral-0 selected:hover:x-bg-lead-50"
:class="{ 'x-selected': selectedNextQuery === nextQuery }"
>
<span
class="x-whitespace-nowrap"
:class="
selectedNextQuery === nextQuery ? 'x-title3 x-title3-md' : 'x-text1 x-text1-lg'
"
>
{{ nextQuery }}
</span>
<CrossTinyIcon v-if="selectedNextQuery === nextQuery" class="x-icon" />
<PlusIcon v-else class="x-icon" />
</button>
</div>
</SlidingPanel>
</div>
<QueryPreview :queryPreviewInfo="queryPreviewInfo" #default="{ totalResults, results }">
<SlidingPanel>
<template #header>
<QueryPreviewButton
:queryPreviewInfo="queryPreviewInfo"
class="x-button x-button-lead x-button-tight x-title3 x-title3-sm desktop:x-title3-md"
>
{{ queryPreviewInfo.query }}
({{ totalResults }})
<ArrowRightIcon class="x-icon-lg" />
</QueryPreviewButton>
</template>

<div class="x-transform-style-3d x-flex x-gap-16 x-pr-8 x-pt-8 desktop:x-pt-16">
<Result
v-for="result in results"
:key="result.id"
:result="result"
class="x-w-[calc(38vw-16px)] x-min-w-[142px] desktop:x-w-[216px]"
/>
</div>
</SlidingPanel>
</QueryPreview>
</div>
</template>
<script lang="ts">
import { computed, defineComponent, PropType, ref, ComputedRef } from 'vue';
import { RelatedPrompt } from '@empathyco/x-types';
import { relatedPromptsXModule } from '../x-module';
import ArrowRightIcon from '../../../components/icons/arrow-right.vue';
import CrossTinyIcon from '../../../components/icons/cross-tiny.vue';
import PlusIcon from '../../../components/icons/plus.vue';
// import { default as Result } from '../../../components/results/result.vue';
import {
QueryPreview,
QueryPreviewButton,
QueryPreviewInfo
} from '../../../x-modules/queries-preview';
import SlidingPanel from '../../../components/sliding-panel.vue';
export default defineComponent({
name: 'RelatedPrompt',
components: {
SlidingPanel,
QueryPreview,
QueryPreviewButton,
// Result,
ArrowRightIcon,
CrossTinyIcon,
PlusIcon
},
xModule: relatedPromptsXModule.name,
props: {
relatedPrompt: { type: Object as PropType<RelatedPrompt>, required: true }
},
setup(props) {
const selectedNextQuery = ref(props.relatedPrompt.nextQueries[0]);
const queryPreviewInfo: ComputedRef<QueryPreviewInfo> = computed(() => ({
query: selectedNextQuery.value
}));

/**
* Handles the click event on a next query button.
*
* @param nextQuery - The clicked next query.
*/
function onClick(nextQuery: string): void {
if (selectedNextQuery.value === nextQuery) {
selectedNextQuery.value = '';
} else {
selectedNextQuery.value = nextQuery;
}
}

return { queryPreviewInfo, selectedNextQuery, onClick };
}
});
</script>
Loading
Loading