how to display data from productListComponentService in spartacus - spartacus-storefront

i want to replace SearchResultsListComponent with my own to display more info than what spartacus provide OOTB when i search for something
i want to show product image, name, stock availability , price , rating

You can replace a component providing ConfigModule in your B2cStorefrontModule(example):
ConfigModule.withConfig({
cmsComponents: {
BannerComponent: {
component: CustomBannerComponent;
}
}
});
There is a page specifically dedicated to component customization:
https://sap.github.io/spartacus-docs/customizing-cms-components

Related

Docusaurus: How can I have multiple versions of different docs in the docs directory?

I'm working with Docusaurus to create a documentation site for 3 different education courses - all within the docs folder.
So I'm looking for a way to have the version be different across folders in there, or figure out what the best strategy for this is.
Right now, in my docusaurus.config.js I have:
module.exports = {
presets: [
'#docusaurus/preset-classic',
docs: {
lastVersion: 'current',
versions: {
current: {
label: '1.0.0',
path: '1.0.0',
},
},
},
],
};
But I'm not sure how to keep track of 3 different versions across 3 different docs all within the same site.
Swizzle the navbar via wrapping
yarn run swizzle #docusaurus/theme-classic NavbarItem/DocsVersionDropdownNavbarItem -- --wrap
Modify the swizzled component like so:
src/theme/NavbarItem/DocsVersionDropdownNavbarItem.js:
import React from "react";
import DocsVersionDropdownNavbarItem from '#theme-original/NavbarItem/DocsVersionDropdownNavbarItem';
import { useLocation } from '#docusaurus/router';
export default function DocsVersionDropdownNavbarItemWrapper(props) {
const { docsPluginId, className, type } = props
const { pathname } = useLocation()
/* (Custom) check if docsPluginId contains pathname
Given that the docsPluginId is 'charge-controller' and the routeBasePath is 'charge-controller', we can check against the current URI (pathname).
If the pathname contains the docsPluginId, we want to show the version dropdown. Otherwise, we don't want to show it.
This gives us one, global, context-aware version dropdown that works with multi-instance setups.
You want to declare a version dropdown for each plugin in your navbarItems config property for this to work well.
const doesPathnameContainDocsPluginId = pathname.includes(docsPluginId)
if (!doesPathnameContainDocsPluginId) {
return null
}
return <DocsVersionDropdownNavbarItem {...props} />;
}
For this to work, you need to have your documentation (based on products) split up using multi-instances: (https://docusaurus.io/docs/docs-multi-instance#docs-navbar-items)
Note that the preset docsPlugin ID always is "default".
You can try to use
import {
useActivePluginAndVersion,
} from '#docusaurus/plugin-content-docs/client';
const version = activePluginAndVersion.activeVersion.name; // use label instead of name if issues arise.
instead to get the current docsPluginId, name or label.
This would be the more "robust" solution I think. That said, we do use the solution I provided above as-is and it works fine for now.

Why does a custom document not show up in the bulk edit mode?

I added a custom document as describied in the documentation. Which worked fine, and I can generate it on a single order.
When I go to the bulk edit mode, the standard documents are there, but not my custom document.
Do I have to do something else besides creating my doucument and type for it?
As of today the document types available in the bulk edit form seem to be hardcoded. You will have to override the component to add your custom document type:
Component.override('sw-bulk-edit-order', {
computed: {
documentsFormFields() {
const formFields = this.$super('documentsFormFields');
formFields.push({
name: 'your_document_technical_name',
labelHelpText: this.$tc('path.to.help-text'),
config: {
componentName: 'plugin-bulk-edit-order-documents-generate-custom-document',
changeLabel: this.$tc('path.to.label'),
},
});
return formFields;
}
},
});
You'll also need register a custom component like plugin-bulk-edit-order-documents-generate-custom-document to set the data for the document like a date or add a comment like for invoices. Have a look at the existing sw-bulk-edit-order-documents-generate-invoice for reference.

Shopify Cart API bundled section rendering in Dawn

I am attempting to build a mini cart using Shopify's base Dawn template.
In assets/cart.js the getSectionsToRender function supplies a section id from a data-id attribute. This is then used by a fetch to the Cart Api which has bundled section rendering.
getSectionsToRender() {
return [
{
id: 'main-cart-items',
section: document.getElementById('main-cart-items').dataset.id || 'main-cart-items',
selector: '.js-contents',
},
{
id: 'cart-icon-bubble',
section: 'cart-icon-bubble',
selector: '.shopify-section'
},
{
id: 'cart-live-region-text',
section: 'cart-live-region-text',
selector: '.shopify-section'
},
{
id: 'main-cart-footer',
section: document.getElementById('main-cart-footer').dataset.id || 'main-cart-footer',
selector: '#main-cart-footer',
}
];
}
updateQuantity(line, quantity, name) {
this.enableLoading(line);
const body = JSON.stringify({
line,
quantity,
sections: this.getSectionsToRender().map((section) => section.section),
sections_url: window.location.pathname
});
fetch(`${routes.cart_change_url}`, {...fetchConfig(), ...{ body }})
.then((response) => {
return response.text();
})
.then((state) => {
const parsedState = JSON.parse(state);
console.log(parsedState.sections);
});
}
When the dynamic section id is used eg template--15179940757682__cart-footer the cart api returns the full main-cart-footer element. However the dynamic section id is not available on other pages and in this context I am using main-cart-footer as the section id. Without the dynamic id the cart api returns main-cart-footer with some of the content missing. I have used the same approach with main-cart-items and there are no issues.
I have tried using sections_url parameter set to /cart to specify the page context but this is not working either.
Anyone have any idea how to get the main-cart-footer without a dynamic section id?
Did you try to create a static section just like "cart-live-region-text"? If you create a section like this and add your code in the section(in your case cart footer where cart subtotal gets updated) then you don't need a dynamic section id, you can write the section name(the section which you create) directly in the section id.
You can checkout the following link👇
https://shopify.dev/api/section-rendering#find-section-ids

Vue: Setting Data by matching route query

I'm attempting to set data fields provided by an array based on the Vue Router query. For example, when someone lands on my website using example.com/?location=texas, I want to set the location data by an array.
An example the array:
locations {
{
slug: "texas",
tagline: "Welcome to Texas",
}, {
slug: "california",
tagline: "Welcome to California",
}
}
I know this should be done using a computed property, however I am unable to get anything functioning. I've tried simple tests like if (this.slug.location === "texas"), and I cannot get the location data to populate. I would also like to provide default data in case there are no route matches.
Any help is extremely appreciated!
Edit:
I can accomplish this in a very manual way. Right now, I'm setting the query in data by the following:
slug: this.$route.query.location
I can display specific text by doing something like:
h3(v-if="slug === 'texas'") This will show for texas
h3(v-else-if="slug === 'california'") This will show for California
h3(v-else) This is default
The issue with this approach is there are various elements I need to customize depending on the slug. Is there any way I can create an array, and move whichever array matches a key in an array to the data??
You should be able to access a query param using the following (link to Vue Router documentation):
this.$route.query.location
So based on what you listed I would do something like...
export default {
computed: {
displayBasedOnLocationQueryParam() {
switch(this.$route.query.location) {
case 'texas':
return 'Welcome to Texas'
default:
return 'hello there, generic person'
}
}
}
}
Note that I'm not using your array explicitly there. The switch statement can be the sole source of that logic, if need be.

how to show agreement Page just one time in ionic 4

I have a problem when working on app.I just want to create agreement page,which will show just one time when the app load first time. After that the page will never show. but in my app that page always showing when the app loaded.Please help me
You could set a boolean variable in storage when the agreement is first displayed, then you check if this variable has been set before showing the agreement.
For example:
import { Storage } from '#ionic/storage';
constructor() {
this.storage.get('agreement_displayed').then(val => {
if (!val) {
this.displayAgreement();
this.storage.set('agreement_displayed', true);
}
});
}