diff --git a/packages/x-components/src/index.ts b/packages/x-components/src/index.ts
index c32bee25e..f215f3c1b 100644
--- a/packages/x-components/src/index.ts
+++ b/packages/x-components/src/index.ts
@@ -26,6 +26,7 @@ export * from './x-modules/popular-searches';
export * from './x-modules/queries-preview';
export * from './x-modules/query-suggestions';
export * from './x-modules/recommendations';
+export * from './x-modules/related-prompts';
export * from './x-modules/related-tags';
export * from './x-modules/scroll';
export * from './x-modules/search';
diff --git a/packages/x-components/src/wiring/events.types.ts b/packages/x-components/src/wiring/events.types.ts
index fbca9c3ef..835e7f679 100644
--- a/packages/x-components/src/wiring/events.types.ts
+++ b/packages/x-components/src/wiring/events.types.ts
@@ -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 */
/**.
@@ -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
*/
@@ -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.
diff --git a/packages/x-components/src/x-modules/related-prompts/components/index.ts b/packages/x-components/src/x-modules/related-prompts/components/index.ts
new file mode 100644
index 000000000..557325c88
--- /dev/null
+++ b/packages/x-components/src/x-modules/related-prompts/components/index.ts
@@ -0,0 +1,2 @@
+export { default as RelatedPrompt } from './related-prompt.vue';
+export { default as RelatedPromptsList } from './related-prompts-list.vue';
diff --git a/packages/x-components/src/x-modules/related-prompts/components/related-prompt.vue b/packages/x-components/src/x-modules/related-prompts/components/related-prompt.vue
new file mode 100644
index 000000000..9b141cf05
--- /dev/null
+++ b/packages/x-components/src/x-modules/related-prompts/components/related-prompt.vue
@@ -0,0 +1,106 @@
+
+
+
+
+ {{ relatedPrompt.suggestionText }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ queryPreviewInfo.query }}
+ ({{ totalResults }})
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/x-components/src/x-modules/related-prompts/components/related-prompts-list.vue b/packages/x-components/src/x-modules/related-prompts/components/related-prompts-list.vue
new file mode 100644
index 000000000..e8eb1fbf0
--- /dev/null
+++ b/packages/x-components/src/x-modules/related-prompts/components/related-prompts-list.vue
@@ -0,0 +1,185 @@
+
diff --git a/packages/x-components/src/x-modules/related-prompts/events.types.ts b/packages/x-components/src/x-modules/related-prompts/events.types.ts
new file mode 100644
index 000000000..589bf822d
--- /dev/null
+++ b/packages/x-components/src/x-modules/related-prompts/events.types.ts
@@ -0,0 +1,14 @@
+import { RelatedPromptsRequest } from '@empathyco/x-types';
+
+/**
+ * Dictionary of the events of RelatedPrompts XModule, where each key is the event name,
+ * and the value is the event payload type or `void` if it has no payload.
+ */
+export interface RelatedPromptsXEvents {
+ /**
+ * Any property of the related-prompts request has changed
+ * Payload: The new related-prompts request or `null` if there is not enough data in the state
+ * to conform a valid request.
+ */
+ RelatedPromptsRequestUpdated: RelatedPromptsRequest | null;
+}
diff --git a/packages/x-components/src/x-modules/related-prompts/index.ts b/packages/x-components/src/x-modules/related-prompts/index.ts
new file mode 100644
index 000000000..0baeb1b99
--- /dev/null
+++ b/packages/x-components/src/x-modules/related-prompts/index.ts
@@ -0,0 +1,5 @@
+export * from './components';
+export * from './events.types';
+export * from './store';
+export * from './wiring';
+export * from './x-module';
diff --git a/packages/x-components/src/x-modules/related-prompts/store/actions/fetch-and-save-related-prompts.action.ts b/packages/x-components/src/x-modules/related-prompts/store/actions/fetch-and-save-related-prompts.action.ts
new file mode 100644
index 000000000..63f83c7d0
--- /dev/null
+++ b/packages/x-components/src/x-modules/related-prompts/store/actions/fetch-and-save-related-prompts.action.ts
@@ -0,0 +1,30 @@
+import { RelatedPrompt, RelatedPromptsRequest } from '@empathyco/x-types';
+import { createFetchAndSaveActions } from '../../../../store/utils/fetch-and-save-action.utils';
+import { RelatedPromptsActionContext } from '../types';
+
+const { fetchAndSave, cancelPrevious } = createFetchAndSaveActions<
+ RelatedPromptsActionContext,
+ RelatedPromptsRequest | null,
+ RelatedPrompt[] | null
+>({
+ fetch({ dispatch }, request) {
+ return dispatch('fetchRelatedPrompts', request);
+ },
+ onSuccess({ commit }, relatedPrompts) {
+ if (relatedPrompts) {
+ commit('setRelatedPromptsProducts', relatedPrompts);
+ }
+ }
+});
+
+/**
+ * Default implementation for
+ * {@link RelatedPromptsActions.fetchAndSaveRelatedPrompts} action.
+ */
+export const fetchAndSaveRelatedPrompts = fetchAndSave;
+
+/**
+ * Default implementation for
+ * {@link RelatedPromptsActions.cancelFetchAndSaveRelatedPrompts} action.
+ */
+export const cancelFetchAndSaveRelatedPrompts = cancelPrevious;
diff --git a/packages/x-components/src/x-modules/related-prompts/store/actions/fetch-related-prompts.action.ts b/packages/x-components/src/x-modules/related-prompts/store/actions/fetch-related-prompts.action.ts
new file mode 100644
index 000000000..5acbfaedf
--- /dev/null
+++ b/packages/x-components/src/x-modules/related-prompts/store/actions/fetch-related-prompts.action.ts
@@ -0,0 +1,19 @@
+import { XPlugin } from '../../../../plugins/x-plugin';
+import { RelatedPromptsXStoreModule } from '../types';
+
+/**
+ * Default implementation for the {@link RelatedPromptsActions.fetchRelatedPrompts}.
+ *
+ * @param _ - The {@link https://vuex.vuejs.org/guide/actions.html | context} of the actions,
+ * provided by Vuex.
+ * @param request - The related prompts request to make.
+ * @returns The related prompts response.
+ */
+export const fetchRelatedPrompts: RelatedPromptsXStoreModule['actions']['fetchRelatedPrompts'] = (
+ _,
+ request
+) => {
+ return request
+ ? XPlugin.adapter.relatedPrompts(request).then(({ relatedPrompts }) => relatedPrompts)
+ : null;
+};
diff --git a/packages/x-components/src/x-modules/related-prompts/store/emitters.ts b/packages/x-components/src/x-modules/related-prompts/store/emitters.ts
new file mode 100644
index 000000000..c91871e06
--- /dev/null
+++ b/packages/x-components/src/x-modules/related-prompts/store/emitters.ts
@@ -0,0 +1,9 @@
+import { createStoreEmitters } from '../../../store';
+import { relatedPromptsXStoreModule } from './module';
+
+/**
+ * {@link StoreEmitters} For the related-prompts module.
+ */
+export const relatedPromptsStoreEmitters = createStoreEmitters(relatedPromptsXStoreModule, {
+ RelatedPromptsRequestUpdated: (_, getters) => getters.request
+});
diff --git a/packages/x-components/src/x-modules/related-prompts/store/getters/request.getter.ts b/packages/x-components/src/x-modules/related-prompts/store/getters/request.getter.ts
new file mode 100644
index 000000000..89cabb8d1
--- /dev/null
+++ b/packages/x-components/src/x-modules/related-prompts/store/getters/request.getter.ts
@@ -0,0 +1,13 @@
+import { RelatedPromptsXStoreModule } from '../types';
+
+/**
+ * Default implementation for the {@link RelatedPromptsGetters.request} getter.
+ *
+ * @param state - Current {@link https://vuex.vuejs.org/guide/state.html | state} of the related
+ * prompts module.
+ *
+ * @returns The related prompts request to fetch data from the API.
+ */
+export const request: RelatedPromptsXStoreModule['getters']['request'] = ({ params, query }) => {
+ return query ? { query, extraParams: params } : null;
+};
diff --git a/packages/x-components/src/x-modules/related-prompts/store/index.ts b/packages/x-components/src/x-modules/related-prompts/store/index.ts
new file mode 100644
index 000000000..5b601e646
--- /dev/null
+++ b/packages/x-components/src/x-modules/related-prompts/store/index.ts
@@ -0,0 +1,6 @@
+export * from './actions/fetch-and-save-related-prompts.action';
+export * from './actions/fetch-related-prompts.action';
+export { request as relatedPromptRequest } from './getters/request.getter';
+export * from './emitters';
+export * from './module';
+export * from './types';
diff --git a/packages/x-components/src/x-modules/related-prompts/store/module.ts b/packages/x-components/src/x-modules/related-prompts/store/module.ts
new file mode 100644
index 000000000..cac37857a
--- /dev/null
+++ b/packages/x-components/src/x-modules/related-prompts/store/module.ts
@@ -0,0 +1,39 @@
+import { setStatus } from '../../../store/utils/status-store.utils';
+import { setQuery } from '../../../store/utils/query.utils';
+import { RelatedPromptsXStoreModule } from './types';
+import {
+ cancelFetchAndSaveRelatedPrompts,
+ fetchAndSaveRelatedPrompts
+} from './actions/fetch-and-save-related-prompts.action';
+import { fetchRelatedPrompts } from './actions/fetch-related-prompts.action';
+import { request } from './getters/request.getter';
+
+export const relatedPromptsXStoreModule: RelatedPromptsXStoreModule = {
+ state: () => ({
+ query: '',
+ relatedPrompts: [],
+ status: 'initial',
+ params: {}
+ }),
+ getters: {
+ request
+ },
+ mutations: {
+ setStatus,
+ setQuery,
+ setParams(state, params) {
+ state.params = params;
+ },
+ setRelatedPromptsProducts(state, products) {
+ state.relatedPrompts = products;
+ },
+ resetRelatedPromptsState(state) {
+ state.relatedPrompts = [];
+ }
+ },
+ actions: {
+ fetchRelatedPrompts,
+ fetchAndSaveRelatedPrompts,
+ cancelFetchAndSaveRelatedPrompts
+ }
+};
diff --git a/packages/x-components/src/x-modules/related-prompts/store/types.ts b/packages/x-components/src/x-modules/related-prompts/store/types.ts
new file mode 100644
index 000000000..0df7c349f
--- /dev/null
+++ b/packages/x-components/src/x-modules/related-prompts/store/types.ts
@@ -0,0 +1,91 @@
+import { RelatedPrompt, RelatedPromptsRequest } from '@empathyco/x-types';
+import { Dictionary } from '@empathyco/x-utils';
+import { QueryMutations, QueryState } from '../../../store/utils/query.utils';
+import { StatusMutations, StatusState } from '../../../store/utils/status-store.utils';
+import { XActionContext, XStoreModule } from '../../../store';
+
+/**
+ * Related prompts module state.
+ */
+export interface RelatedPromptsState extends StatusState, QueryState {
+ /** The list of the related-prompts, related to the `query` property of the state. */
+ relatedPrompts: RelatedPrompt[];
+ /** The extra params property of the state. */
+ params: Dictionary;
+}
+
+/**
+ * Related prompts module getters.
+ */
+export interface RelatedPromptsGetters {
+ /**
+ * Request object to retrieve the related prompts using the search adapter, or null if there is
+ * no valid data to conform a valid request.
+ */
+ request: RelatedPromptsRequest | null;
+}
+
+/**
+ * Related prompts module mutations.
+ */
+export interface RelatedPromptsMutations extends StatusMutations, QueryMutations {
+ /**
+ * Sets the extra params of the module.
+ *
+ * @param params - The new extra params.
+ */
+ setParams(params: Dictionary): void;
+ /**
+ * Sets the related prompts of the module.
+ *
+ * @param relatedPrompts - The new related prompts to save to the state.
+ */
+ setRelatedPromptsProducts(products: RelatedPrompt[]): void;
+ /**
+ * Resets the related prompts state.
+ */
+ resetRelatedPromptsState(): void;
+}
+
+/**
+ * Related prompts module actions.
+ */
+export interface RelatedPromptsActions {
+ /**
+ * Requests a new set of related prompts for the module query, and returns them.
+ *
+ * @param request - The related prompts request.
+ */
+ fetchRelatedPrompts(request: RelatedPromptsRequest | null): RelatedPrompt[] | null;
+ /**
+ * Requests a new set of related prompts and stores them in the module.
+ *
+ * @param request - The related prompts request.
+ */
+ fetchAndSaveRelatedPrompts(request: RelatedPromptsRequest | null): void;
+ /**
+ * Cancels / interrupt {@link RelatedPromptsActions.fetchAndSaveRelatedPrompts}
+ * synchronous promise.
+ */
+ cancelFetchAndSaveRelatedPrompts(): void;
+}
+
+/**
+ * Related prompts store module.
+ */
+export type RelatedPromptsXStoreModule = XStoreModule<
+ RelatedPromptsState,
+ RelatedPromptsGetters,
+ RelatedPromptsMutations,
+ RelatedPromptsActions
+>;
+
+/**
+ * Alias type for actions context of the {@link RelatedPromptsXStoreModule}.
+ */
+export type RelatedPromptsActionContext = XActionContext<
+ RelatedPromptsState,
+ RelatedPromptsGetters,
+ RelatedPromptsMutations,
+ RelatedPromptsActions
+>;
diff --git a/packages/x-components/src/x-modules/related-prompts/types.ts b/packages/x-components/src/x-modules/related-prompts/types.ts
new file mode 100644
index 000000000..3b26690fb
--- /dev/null
+++ b/packages/x-components/src/x-modules/related-prompts/types.ts
@@ -0,0 +1,10 @@
+import { RelatedPrompt } from '@empathyco/x-types';
+import { ListItem } from '../../utils';
+
+/**
+ * Related promts group interface for the RelatedPrompts.
+ */
+export interface RelatedPromptsGroup extends ListItem {
+ modelName: 'RelatedPromptsGroup';
+ relatedPrompts: RelatedPrompt[];
+}
diff --git a/packages/x-components/src/x-modules/related-prompts/wiring.ts b/packages/x-components/src/x-modules/related-prompts/wiring.ts
new file mode 100644
index 000000000..bf229a306
--- /dev/null
+++ b/packages/x-components/src/x-modules/related-prompts/wiring.ts
@@ -0,0 +1,95 @@
+import {
+ namespacedWireCommit,
+ namespacedWireCommitWithoutPayload,
+ namespacedWireDispatch,
+ namespacedWireDispatchWithoutPayload
+} from '../../wiring/namespaced-wires.factory';
+import {
+ NamespacedWireCommit,
+ NamespacedWireCommitWithoutPayload
+} from '../../wiring/namespaced-wiring.types';
+import { createWiring } from '../../wiring/wiring.utils';
+
+/**
+ * `relatedPrompts` {@link XModuleName | XModule name}.
+ */
+const moduleName = 'relatedPrompts';
+
+/**
+ * WireCommit for {@link RelatedPromptsXModule}.
+ */
+const wireCommit: NamespacedWireCommit = namespacedWireCommit(moduleName);
+
+/**
+ * WireCommitWithoutPayload for {@link RelatedPromptsXModule}.
+ */
+const wireCommitWithoutPayload: NamespacedWireCommitWithoutPayload =
+ namespacedWireCommitWithoutPayload(moduleName);
+
+/**
+ * WireDispatch for {@link RelatedPromptsXModule}.
+ */
+const wireDispatch = namespacedWireDispatch(moduleName);
+
+/**
+ * WireDispatchWithoutPayload for {@link RelatedPromptsXModule}.
+ */
+const wireDispatchWithoutPayload = namespacedWireDispatchWithoutPayload(moduleName);
+
+/**
+ * Sets the related prompts state `query`.
+ */
+const setRelatedPromptsQuery = wireCommit('setQuery');
+
+/**
+ * Sets the related prompts state `query` from url params.
+ */
+const setRelatedPromptsQueryFromUrl = wireCommit(
+ 'setQuery',
+ ({ eventPayload: { query } }) => query
+);
+
+/**
+ * Sets the related prompts state `params`.
+ */
+export const setRelatedPromptsExtraParams = wireCommit('setParams');
+
+/**
+ * Resets the related prompts state.
+ */
+const resetRelatedPromptsStateWire = wireCommitWithoutPayload('resetRelatedPromptsState');
+
+/**
+ * Fetches and saves the related prompts response.
+ */
+const fetchAndSaveRelatedPromptsResponseWire = wireDispatch('fetchAndSaveRelatedPrompts');
+
+/**
+ * Cancels the fetch and save related prompts response.
+ */
+const cancelFetchAndSaveSearchResponseWire = wireDispatchWithoutPayload(
+ 'cancelFetchAndSaveRelatedPrompts'
+);
+
+/**
+ * Wiring configuration for the {@link RelatedPromptsXModule | related prompts module}.
+ */
+export const relatedPromptsWiring = createWiring({
+ ParamsLoadedFromUrl: {
+ setRelatedPromptsQueryFromUrl
+ },
+ UserAcceptedAQuery: {
+ setRelatedPromptsQuery
+ },
+ UserClearedQuery: {
+ cancelFetchAndSaveSearchResponseWire,
+ resetRelatedPromptsStateWire,
+ setRelatedPromptsQuery
+ },
+ RelatedPromptsRequestUpdated: {
+ fetchAndSaveRelatedPromptsResponseWire
+ },
+ ExtraParamsChanged: {
+ setRelatedPromptsExtraParams
+ }
+});
diff --git a/packages/x-components/src/x-modules/related-prompts/x-module.ts b/packages/x-components/src/x-modules/related-prompts/x-module.ts
new file mode 100644
index 000000000..fb5abd538
--- /dev/null
+++ b/packages/x-components/src/x-modules/related-prompts/x-module.ts
@@ -0,0 +1,24 @@
+import { XPlugin } from '../../plugins/x-plugin';
+import { XModule } from '../x-modules.types';
+import { RelatedPromptsXStoreModule } from './store/types';
+import { relatedPromptsXStoreModule } from './store/module';
+import { relatedPromptsStoreEmitters } from './store/emitters';
+import { relatedPromptsWiring } from './wiring';
+
+/**
+ * RelatedPrompts {@link XModule} alias.
+ */
+export type RelatedPromptsXModule = XModule;
+
+/**
+ * Related Prompts {@link XModule} implementation. This module is auto-registered as soon as you
+ * import any component from the `related-prompts` entry point.
+ */
+export const relatedPromptsXModule: RelatedPromptsXModule = {
+ name: 'relatedPrompts',
+ storeModule: relatedPromptsXStoreModule,
+ storeEmitters: relatedPromptsStoreEmitters,
+ wiring: relatedPromptsWiring
+};
+
+XPlugin.registerXModule(relatedPromptsXModule);
diff --git a/packages/x-components/src/x-modules/x-modules.types.ts b/packages/x-components/src/x-modules/x-modules.types.ts
index 858ec432e..c9f97a7a1 100644
--- a/packages/x-components/src/x-modules/x-modules.types.ts
+++ b/packages/x-components/src/x-modules/x-modules.types.ts
@@ -20,6 +20,7 @@ import { SemanticQueriesXModule } from './semantic-queries/x-module';
import { TaggingXModule } from './tagging';
import { UrlXModule } from './url';
import { ExperienceControlsXModule } from './experience-controls/x-module';
+import { RelatedPromptsXModule } from './related-prompts/x-module';
/**
* Gives each {@link XModule} a name, that can be used to retrieve then its value.
@@ -38,6 +39,7 @@ export interface XModulesTree {
queriesPreview: QueriesPreviewXModule;
querySuggestions: QuerySuggestionsXModule;
recommendations: RecommendationsXModule;
+ relatedPrompts: RelatedPromptsXModule;
relatedTags: RelatedTagsXModule;
scroll: ScrollXModule;
search: SearchXModule;