@rocketsearch/nuxt-uappi 0.2.5 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/package.json +1 -1
- package/runtime/components/RocketBanner.vue +30 -7
- package/runtime/rocket.js +2 -0
package/README.md
CHANGED
|
@@ -15,5 +15,6 @@ modules: [
|
|
|
15
15
|
|
|
16
16
|
Landing page ("Personalizado" no painel): `<RocketLanding>` mostra todas as vitrines da landing, na ordem do
|
|
17
17
|
painel. O identificador vem do nome da rota (`/black-friday` → `black-friday`) ou de `custom-key="..."`.
|
|
18
|
+
Banners da landing: `<RocketBanner page-type="custom" />`, com a mesma regra do identificador.
|
|
18
19
|
|
|
19
20
|
Documentação completa: https://api.rocketsearch.com.br/sdk/uappi/docs.html
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
3
|
:class="['rocket-search', 'rocket-search__banner-slot', { 'rocket-search--empty': !waiting && !banners.length }]"
|
|
4
|
-
:data-rocket-banner-position="position"
|
|
4
|
+
:data-rocket-banner-position="position || undefined"
|
|
5
5
|
>
|
|
6
6
|
<!-- Skeleton só com proporção declarada: sem saber a altura, ele é que causaria o pulo. -->
|
|
7
7
|
<div v-if="waiting && ratio" class="rocket-search__banner-skeleton" :style="{ aspectRatio: ratioCss }" aria-hidden="true" />
|
|
@@ -26,12 +26,14 @@
|
|
|
26
26
|
import RocketBannerItem from './banner/RocketBannerItem.vue';
|
|
27
27
|
import { exactWidth, isHeroSlot } from '../banner.js';
|
|
28
28
|
|
|
29
|
+
const positionOf = b => (b && ((b.placement && b.placement.position) || b.position)) || '';
|
|
30
|
+
|
|
29
31
|
export default {
|
|
30
32
|
name: 'RocketBanner',
|
|
31
33
|
components: { RocketBannerItem },
|
|
32
34
|
props: {
|
|
33
|
-
// placement.position cadastrada no painel (hero, top, middle...).
|
|
34
|
-
position: { type: String,
|
|
35
|
+
// placement.position cadastrada no painel (hero, top, middle...). Obrigatória fora da landing.
|
|
36
|
+
position: { type: String, default: '' },
|
|
35
37
|
// ssr: vem no HTML (hero/LCP). ondemand: busca só quando o slot chega perto da viewport.
|
|
36
38
|
loading: {
|
|
37
39
|
type: String,
|
|
@@ -40,6 +42,9 @@ export default {
|
|
|
40
42
|
},
|
|
41
43
|
// Força o pageType; sem ele vem da página atual (dadosPageAtual do tema).
|
|
42
44
|
pageType: { type: String, default: '' },
|
|
45
|
+
// Landing (page-type="custom"): identificador no painel; sem ele, o nome da rota
|
|
46
|
+
// (/black-friday -> black-friday). A landing não tem posição: vêm todos os banners dela.
|
|
47
|
+
customKey: { type: String, default: '' },
|
|
43
48
|
limit: { type: Number, default: 0 },
|
|
44
49
|
// Proporção do slot ("16/9", "3:1") — reserva a caixa e liga o skeleton.
|
|
45
50
|
ratio: { type: String, default: '' },
|
|
@@ -65,11 +70,22 @@ export default {
|
|
|
65
70
|
return this.loading === 'ssr';
|
|
66
71
|
},
|
|
67
72
|
computed: {
|
|
73
|
+
landingKey () {
|
|
74
|
+
if (this.pageType !== 'custom') return '';
|
|
75
|
+
if (this.customKey) return this.customKey;
|
|
76
|
+
return ((this.$route && this.$route.path) || '').split('/').filter(Boolean).pop() || '';
|
|
77
|
+
},
|
|
68
78
|
ratioCss () {
|
|
69
79
|
return String(this.ratio).trim().replace(':', ' / ');
|
|
70
80
|
}
|
|
71
81
|
},
|
|
72
82
|
watch: {
|
|
83
|
+
// Mesma página, outra landing (rota dinâmica reaproveita o componente): busca de novo.
|
|
84
|
+
landingKey () {
|
|
85
|
+
if (!this.requested) return;
|
|
86
|
+
this.requested = false;
|
|
87
|
+
this.tryLoad();
|
|
88
|
+
},
|
|
73
89
|
// O contexto da página chega por setDadosPageAtual (o plugin traduz para $rocket.setPage).
|
|
74
90
|
'$store.state.dadosPageAtual' () {
|
|
75
91
|
if (this.loading === 'ssr' || this.visible) this.tryLoad();
|
|
@@ -101,16 +117,23 @@ export default {
|
|
|
101
117
|
if (process.client && this.$el && this.$el.clientWidth) {
|
|
102
118
|
this.width = exactWidth(this.$el.clientWidth, window.devicePixelRatio);
|
|
103
119
|
}
|
|
104
|
-
const
|
|
105
|
-
const
|
|
120
|
+
const key = this.landingKey;
|
|
121
|
+
const list = this.pageType === 'custom'
|
|
122
|
+
? (key ? await this.$rocket.getBannersByContext('custom', { customKey: key }) : [])
|
|
123
|
+
: await this.$rocket.getBannersByContext(this.pageType || undefined, { position: this.position });
|
|
124
|
+
// Troca rápida de landing: a resposta da anterior não sobrescreve a atual.
|
|
125
|
+
if (key !== this.landingKey) return;
|
|
126
|
+
const mine = this.pageType === 'custom' ? list : list.filter(b => positionOf(b) === this.position);
|
|
106
127
|
this.banners = this.limit > 0 ? mine.slice(0, this.limit) : mine;
|
|
107
128
|
this.waiting = false;
|
|
108
129
|
},
|
|
109
130
|
|
|
110
131
|
itemProps (index) {
|
|
111
|
-
|
|
132
|
+
// Na landing o slot é a posição do próprio banner.
|
|
133
|
+
const position = this.position || positionOf(this.banners[index]);
|
|
134
|
+
const hero = isHeroSlot(position) && index === 0;
|
|
112
135
|
return {
|
|
113
|
-
position
|
|
136
|
+
position,
|
|
114
137
|
slideIndex: index,
|
|
115
138
|
loading: hero ? 'eager' : 'lazy',
|
|
116
139
|
fetchPriority: hero ? 'high' : '',
|
package/runtime/rocket.js
CHANGED
|
@@ -320,6 +320,7 @@ export function createRocket (config) {
|
|
|
320
320
|
};
|
|
321
321
|
|
|
322
322
|
// Só banners (DTO banner-native). Gated pela flag `banners`: loja sem ela recebe [].
|
|
323
|
+
// options.customKey: identificador da landing (pageType=custom); sem ele a API responde 400.
|
|
323
324
|
rocket.getBannersByContext = async function (type, options) {
|
|
324
325
|
const pageType = resolvePageType(type);
|
|
325
326
|
if (!pageType) return [];
|
|
@@ -327,6 +328,7 @@ export function createRocket (config) {
|
|
|
327
328
|
try {
|
|
328
329
|
const sessionId = await getSessionIdWithTimeout();
|
|
329
330
|
const params = { storeId: config.storeId, pageType, sessionId, position: opts.position };
|
|
331
|
+
if (pageType === 'custom') params.customKey = opts.customKey;
|
|
330
332
|
const res = await fetch(config.apiUrl + '/banners/context?' + query(params), { headers: headers() });
|
|
331
333
|
if (!res.ok) return [];
|
|
332
334
|
const banners = await res.json();
|