Skip to content

Commit

Permalink
feat: integrate backroom layer (#447)
Browse files Browse the repository at this point in the history
  • Loading branch information
diegopf authored May 7, 2024
1 parent d652330 commit f33aa98
Show file tree
Hide file tree
Showing 11 changed files with 159 additions and 51 deletions.
1 change: 1 addition & 0 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
<body>
<%= htmlWebpackPlugin.options.__injectedHome__ %>
<script src="./snippet-script.js"></script>
<script type="module" src="https://assets.motive.co/wysiwyg/wysiwyg.js"></script>
<!-- built files will be auto injected -->
</body>
</html>
17 changes: 17 additions & 0 deletions public/snippet-script.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,20 @@ window.initX = {
}
]
};

window.addEventListener('load', () => {
window.wysiwyg.setConfig({
auth: {
baseUrl: 'https://iam.empathy.co',
clientId: 'wysiwyg'
},
analytics: {
baseUrl: 'https://api.staging.empathy.co/statistics/v2'
},
lang,
instance,
audience: 'enterprise',
appContainerSelector: '.x-root-container',
searchLayerSelector: '.x'
});
});
35 changes: 33 additions & 2 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,18 @@
<Tagging />
<UrlHandler />
<ExperienceControls />
<MainModal v-if="isOpen" />
<MainModal v-if="isOpen" data-wysiwyg="layer" />
</div>
</template>

<script lang="ts">
import { SnippetCallbacks, SnippetConfig, XOn, XProvide } from '@empathyco/x-components';
import {
SnippetCallbacks,
SnippetConfig,
UrlParams,
XOn,
XProvide
} from '@empathyco/x-components';
import { ExperienceControls } from '@empathyco/x-components/experience-controls';
import { Tagging } from '@empathyco/x-components/tagging';
import { QueryPreviewInfo } from '@empathyco/x-components/queries-preview';
Expand All @@ -37,6 +43,31 @@
@XOn(['UserOpenXProgrammatically', 'UserClickedOpenX'])
open(): void {
this.isOpen = true;
window.wysiwyg?.open();
}
@XOn(['UserClickedCloseX'])
close(): void {
window.wysiwyg?.close();
}
@XOn(['UserAcceptedAQuery'])
async goToLoginWysiwyg(query: string): Promise<void> {
if (/^::\s*login/.test(query)) {
await window.wysiwyg?.goToLogin();
}
}
@XOn(['ParamsLoadedFromUrl'])
async requestAuthWysiwyg(payload: UrlParams): Promise<void> {
try {
if (window.wysiwyg) {
await window.wysiwyg?.requestAuth();
window.InterfaceX?.search();
}
} catch (_) {
// No error handling
}
}
@Inject('snippetConfig')
Expand Down
1 change: 1 addition & 0 deletions src/components/pre-search/custom-query-preview.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
:queriesPreviewInfo="queriesPreviewInfo"
:persistInCache="true"
:queryFeature="queryFeature"
data-wysiwyg="query-previews"
#default="{ queryPreviewInfo, totalResults, results, queryTagging }"
>
<div class="x-mb-40 x-flex x-flex-col x-gap-2 desktop:x-mb-64 desktop:x-gap-16">
Expand Down
7 changes: 5 additions & 2 deletions src/components/predictive-layer/sliding-recommendations.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<div v-if="$x.recommendations.length > 0" class="x-flex x-flex-col x-gap-12">
<h1
class="x-title4 x-title4-sm x-flex x-h-32 x-items-center x-pt-16 x-pl-24 x-uppercase desktop:x-pl-0 desktop:x-pt-0"
class="x-title4 x-title4-sm x-flex x-h-32 x-items-center x-pl-24 x-pt-16 x-uppercase desktop:x-pl-0 desktop:x-pt-0"
>
{{ $t('recommendations.title') }}
</h1>
Expand All @@ -16,7 +16,10 @@
<ChevronLeftIcon class="x-icon-lg" />
</template>

<Recommendations class="x-flex x-flex-row x-gap-12 x-pl-16 desktop:x-pl-0">
<Recommendations
class="x-flex x-flex-row x-gap-12 x-pl-16 desktop:x-pl-0"
data-wysiwyg="recommendations"
>
<template #default="{ recommendation }">
<DisplayClickProvider resultFeature="topclicked_recommendations">
<Result
Expand Down
3 changes: 2 additions & 1 deletion src/components/results/custom-recommendations.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<div
v-if="$x.recommendations.length > 0"
class="x-flex x-flex-col x-items-start x-gap-16 x-pb-32 desktop:x-items-center desktop:x-gap-24"
data-wysiwyg="recommendations"
>
<h1 class="x-title1 x-title1-sm x-text-neutral-90 desktop:x-title1-md">
{{ $t('recommendations.title') }}
Expand All @@ -14,7 +15,7 @@
:animation="staggeredFadeAndSlide"
:columns="columns"
:items="recommendations"
class="x-gap-y-32 x-gap-x-16"
class="x-gap-x-16 x-gap-y-32"
>
<Result :result="result" data-test="recommendation-item" />
</BaseGrid>
Expand Down
4 changes: 4 additions & 0 deletions src/components/results/result.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
:item="result"
tag="article"
class="x-result x-group/result x-flex x-flex-col x-gap-4"
data-wysiwyg="result"
:data-wysiwyg-id="result.id"
:data-wysiwyg-image-url="result.images ? result.images[0] : ''"
:data-wysiwyg-title="result.name"
>
<div class="x-relative">
<BaseResultLink class="x-result__picture" :result="result">
Expand Down
1 change: 1 addition & 0 deletions src/components/search/custom-semantic-queries.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
:queriesPreviewInfo="queries.map(q => ({ query: q }))"
#default="{ queryPreviewInfo: { query }, results, totalResults }"
class="x-flex x-flex-col x-gap-64"
data-wysiwyg="query-previews"
>
<CustomSlidingPanel>
<template #header>
Expand Down
8 changes: 6 additions & 2 deletions src/components/search/results/results.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
<template>
<ResultsList v-if="$x.totalResults || $x.noResults" v-infinite-scroll:main-scroll>
<ResultsList
v-if="$x.totalResults || $x.noResults"
v-infinite-scroll:main-scroll
data-wysiwyg="results"
>
<PromotedsList>
<BannersList>
<NextQueriesList
Expand All @@ -9,7 +13,7 @@
:showOnlyAfterOffset="$x.partialResults.length > 0"
>
<BaseVariableColumnGrid
class="x-gap-y-32 x-gap-x-16"
class="x-gap-x-16 x-gap-y-32"
:animation="staggeredFadeAndSlide"
:columns="columns"
data-test="base-grid"
Expand Down
6 changes: 6 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ import { getInstallXOptions } from './x-components/plugin.options';
declare global {
interface Window {
__enableVueDevtools__?: boolean;
wysiwyg?: {
goToLogin: () => Promise<void>;
requestAuth: () => Promise<void>;
open: () => Promise<void>;
close: () => Promise<void>;
};
}
}

Expand Down
127 changes: 83 additions & 44 deletions src/x-components/plugin.options.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { InstallXOptions, SnippetConfig } from '@empathyco/x-components';
import { filter, InstallXOptions, SnippetConfig } from '@empathyco/x-components';
import { I18n, cssInjector } from '@empathyco/x-archetype-utils';
import { setSearchQuery } from '@empathyco/x-components/search';
import { addQueryToHistoryQueries } from '@empathyco/x-components/history-queries';
import { setUrlQuery } from '@empathyco/x-components/url';
import App from '../App.vue';
import * as messages from '../i18n/messages';
import store from '../store';
Expand All @@ -9,55 +12,91 @@ import { mergeSemanticQueriesConfigWire } from './wiring/semantic-queries.wiring

const device = useDevice();

const setSearchQueryFiltered = filter(
setSearchQuery,
({ eventPayload }) => !eventPayload.startsWith('::')
);

const addQueryToHistoryQueriesFiltered = filter(
addQueryToHistoryQueries,
({ eventPayload }) => !eventPayload.startsWith('::')
);

const setUrlQueryFiltered = filter(
setUrlQuery,
({ eventPayload }) => !eventPayload.startsWith('::')
);

/**
* Function that returns the options to install x-components.
*
* Returns - the InstallXOptions.
*/
export async function getInstallXOptions(): Promise<InstallXOptions> {
if (process.env.VUE_APP_DEVELOPMENT_DOCKER) {
const { overrideAdapter } = await import('../adapter/docker.adapter');
overrideAdapter(adapter);
}
return {
adapter,
store,
app: App,
domElement: getDomElement,
xModules: {
facets: {
config: {
filtersStrategyForRequest: 'leaves-only'
}
},
semanticQueries: {
config: {
threshold: 50,
maxItemsToRequest: 10
},
wiring: {
SemanticQueriesConfigProvided: {
mergeSemanticQueriesConfigWire
}
if (process.env.VUE_APP_DEVELOPMENT_DOCKER) {
const { overrideAdapter } = await import('../adapter/docker.adapter');
overrideAdapter(adapter);
}
return {
adapter,
store,
app: App,
domElement: getDomElement,
xModules: {
facets: {
config: {
filtersStrategyForRequest: 'leaves-only'
}
},
semanticQueries: {
config: {
threshold: 50,
maxItemsToRequest: 10
},
wiring: {
SemanticQueriesConfigProvided: {
mergeSemanticQueriesConfigWire
}
}
},
search: {
wiring: {
UserAcceptedAQuery: {
setSearchQuery: setSearchQueryFiltered
}
}
},
historyQueries: {
wiring: {
UserAcceptedAQuery: {
addQueryToHistoryQueries: addQueryToHistoryQueriesFiltered
}
}
},
async installExtraPlugins({ vue, snippet }) {
const i18n = await I18n.create({
locale: snippet.uiLang,
device: (snippet.device as string) ?? device.deviceName.value,
fallbackLocale: 'en',
messages
});
vue.use(i18n);
vue.prototype.$setLocale = i18n.setLocale.bind(i18n);
vue.prototype.$setLocaleDevice = i18n.setDevice.bind(i18n);
url: {
wiring: {
UserAcceptedAQuery: {
setUrlQuery: setUrlQueryFiltered
}
}
}
},
async installExtraPlugins({ vue, snippet }) {
const i18n = await I18n.create({
locale: snippet.uiLang,
device: (snippet.device as string) ?? device.deviceName.value,
fallbackLocale: 'en',
messages
});
vue.use(i18n);
vue.prototype.$setLocale = i18n.setLocale.bind(i18n);
vue.prototype.$setLocaleDevice = i18n.setDevice.bind(i18n);

return {
i18n: i18n.vueI18n
};
}
};
return {
i18n: i18n.vueI18n
};
}
};
}

/**
Expand All @@ -67,19 +106,19 @@ export async function getInstallXOptions(): Promise<InstallXOptions> {
* @returns The DOM element.
*/
function getDomElement({ isolate }: SnippetConfig): Element {
const container = document.createElement('div');
container.classList.add('x-root-container');
const domElement = document.createElement('div');

if (isolate || process.env.NODE_ENV === 'production') {
const container = document.createElement('div');
container.classList.add('x-root-container');
const shadowRoot = container.attachShadow({ mode: 'open' });
shadowRoot.appendChild(domElement);
document.body.appendChild(container);
cssInjector.setHost(shadowRoot);
} else {
document.body.appendChild(domElement);
container.appendChild(domElement);
cssInjector.setHost(document.head);
}

document.body.appendChild(container);
return domElement;
}

0 comments on commit f33aa98

Please sign in to comment.