Add links to custom pages in the keystone Admin UI - keystonejs

I am using keystone 4.0 beta version and want to be able to add links to my own routes and templates, which are not keystone lists, in the admin UI. I found the following example to do so in the navigation (by adding an object instead of string):
keystone.set( "nav", {
"content": [
"posts",
"post-categories",
"enquiries",
{
label: "reports",
key: "reports",
path: "/api/reports"
},
]
});
I guess this worked in older versions but since the new version uses React it only changes the URL in the browser without actually redirecting to the page. Is there any way to workaround this?

Related

Vue 2: configure router to navigate to other product using relative path

I am new to vue but I need to fix some issue.
I have app with some products and its verions. I am able to view details of some version when accessing the path: /products/details/productId/versionId
Let's say I am accessing product A and its version 1 and path to it is:
/products/details/product_A_Id/version_1_Id
In the description of this product version there is a link to different product and different version set as:
Product_B/Version_1
So when I am accessing this link I am redirected to: /products/details/product_A_Id/product_B_Id/version_1_Id and then redirected to 404 as there is no such path.
After changing link to Product_B/Version_1 I am redirected to correct product and correct version. But the issue is that there are a lot of links that are pasted in without ../ and using some db script will not be an easy solution.
Is there any easy way that will fix above issue? Any router method that will do what it takes to nevigate me to correct product version?
You can use <router-link to="/product_B_Id/version_1_Id">Product_B/Version_1</router-link>
I have achieved it by adding children path in vue router and redirecting it to page productId/versionId:
{
path: 'products/details/:productid',
name: 'productsdetails',
component: ProductDetails,
},
children: [
{
path: ':productid/:versionid',
redirect: {
name: 'releaseDetails',
},
}
]
},

How to use vue component across multiple node projects?

I'm trying to build a website builder within the drag-and-drop abilities via using Vue3. So, the user will be playing with the canvas and generate a config structure that going to post the backend. Furthermore, the server-side will generate static HTML according to this config.
Eventually, the config will be like the below and it works perfectly. The config only can have HTML tags and attributes currently. Backend uses h() function to generate dom tree.
My question is: can I use .vue component that will generate on the server side as well? For example, the client-side has a Container.vue file that includes some interactions, styles, etc. How can the backend recognize/resolve this vue file?
UPDATE:
Basically, I want to use the Vue component that exists on the Client side on the backend side to generate HTML strings same as exactly client side. (including styles, interactions etc).
Currently, I'm able to generate HTML string via the below config but want to extend/support Vue component itself.
Note: client and server are completely different projects. Currently, server takes config and runs createSSRApp, renderToString methods.
Here is the gist of how server would handle the API:
https://gist.github.com/yulafezmesi/162eafcf7f0dcb3cb83fb822568a6126
{
id: "1",
tagName: "main",
root: true,
type: "container",
properties: {
class: "h-full",
style: {
width: "800px",
transform: "translateZ(0)",
},
},
children: [
{
id: "9",
type: "image",
tagName: "figure",
interactive: true,
properties: {
class: "absolute w-28",
style: {
translate: "63px 132px",
},
},
},
],
}
This might get you started: https://vuejs.org/guide/scaling-up/ssr.html#rendering-an-app
From the docs:
// this runs in Node.js on the server.
import { createSSRApp } from 'vue'
// Vue's server-rendering API is exposed under `vue/server-renderer`.
import { renderToString } from 'vue/server-renderer'
const app = createSSRApp({
data: () => ({ count: 1 }),
template: `<button #click="count++">{{ count }}</button>`
})
renderToString(app).then((html) => {
console.log(html)
})
I guess extract the template from request or by reading the submitted Vue file and use that as the template parameter value

Custom PageLayoutComponent

To have specific layout for some pages at our project we create few custom PageLayoutComponent's. Some contfiguration example:
{
// #ts-ignore
path: null,
canActivate: [CmsPageGuard],
component: CartPageLayoutComponent,
data: {
cxRoute: 'cart',
cxContext: {
[ORDER_ENTRIES_CONTEXT]: ActiveCartOrderEntriesContextToken,
},
},
},
All work fine with storefront until you will not try to select specific page at smartedit. As result it not use our custom CartPageLayoutComponent, but will use PageLayoutComponent for rendering.
Probably this is because it's not a normal route navigation. Can somebody from spartacus team suggest how this bug can be fixed?
Probably this is because it's not a normal route navigation
I believe your Route should be recognized normally, there is nothing special in adding a custom Angular Route.
So I guess there is something special about the page or URL of Spartacus Storefront that runs in your SmartEdit.
It's hard to tell the reason of your problem without more debugging.
You said your app works as expected when run differently (locally?), but when used in SmartEdit, then there is a problem. Please identify factors that makes the run SmartEdit different from your (local?) run. And try to isolate them. Guesses from top of my head:
production vs dev mode of the build?
exact URL of the cart page?
any difference in configuration between a local version and deployed one to be used in SmartEdit?
I would also add some debugging code to better know which routes configs are available and which one is used for the current route. For debugging purposes please add the following constructor logic in your AppModule:
export class AppModule {
// on every page change, log:
// - active url
// - the Route object that was matched with the active URL
// - all the Route objects provided to Angular Router
constructor(router: Router) {
router.events.subscribe((event) => {
if (event instanceof NavigationEnd) {
console.log({
activeUrl: router.url,
activeRouteConfig:
router.routerState.snapshot.root.firstChild.routeConfig,
allRoutesConfigs: router.config,
});
}
});
}
}
The pages opened in SmartEdit have the same route of cx-preview (e.g. to open faq page in smartedit, request is https://localhost:4200/electronics-spa/en/USD/cx-preview?cmsTicketId=xxxxx. backend can get page id from cmsTicketId). If you want to change the page layout, you can consider use PageLayoutHandler. Spartacus has some PageLayoutHandlers, e.g.
{
provide: PAGE_LAYOUT_HANDLER,
useExisting: CartPageLayoutHandler,
multi: true,
},

PDP Custom Routes defined in a module not working

I'm following the Spartacus bootcamp sample for routing https://github.com/SAP/spartacus-bootcamp/tree/77b7474c9538eaa1032062ad3c6d461fb1fc7517/src/app/features/routing
My problem is when I have configured the custom PDP
imports: [
CommonModule,
// dependent module for semantic URLs like cxUrl
UrlModule,
// standard non-spartacus routes
RouterModule.forChild(staticRoutes),
// configure product routes
ConfigModule.withConfig({
routing: {
routes: {
product: {
paths: [
'product/:manufacturer/:firstCategoryName/:productCode/:prettyName',
'product/:manufacturer/:productCode/:prettyName',
'product/:productCode/:name',
],
},
},
},
} as RoutingConfig),
//code mapping in the routes
ConfigModule.withConfig({
paramsMapping: {
productCode: 'code',
},
} as RouteConfig),
The new PDP routes are never used in the Storefront. I can see in the browser console that the custom product properties firstCategoryName and prettyName are properly settled from the normalizers/converters of the sample...
Any insight what can be going on?
Thanks!
Fernando
I think it will also depend on whether/not the manufacturer property is populated as well. By default the manufacturer field is not requested in the productSearch OCC call, so will not be populated on the product object (see default-occ-product-config.ts in the Spartacus code) - this means that on product listing pages (category & search) those two paths will not resolve, and are therefore ignored.

Is it possible to use the default tabs with 1.X api

I am using the "new" spotify apps api and their documentation about the default tabs only seem to be relevant if you are using the old 0.X api.
I can create the tabs with my manifest using the below code. But I can't seem to fin a way to interact with them.
"DefaultTabs": [
{
"arguments": "test",
"title": { "en": "test" }
},
{
"arguments": "test2",
"title": { "en": "test2" }
}
]
I found a example of interacting with the default tabs that looks like this:
sp = getSpotifyApi(1);
// detects arguments value for tab
sp.core.addEventListener("argumentsChanged", function (event) {
console.log('args changed', sp.core.getArguments());
});
But I keep getting the error message "Uncaught ReferenceError: getSpotifyApi is not defined " and according to this post Cannot use the "getSpotifyApi" function in spotify app it's due to the fact that it's the 0.X way of interacting with the api.
Cannot use the "getSpotifyApi" function in spotify app
The only thing close to it that i found where the 1.X tab bars, they dont resemble a classic spotify tab bar, more like regulair gray buttons.
https://developer.spotify.com/docs/apps/views/1.0/tabbar-tabbar.html
anyone have any ideas here?
Looks like your tabbar docs point to the proper usage documented on https://developer.spotify.com/docs/apps/views/1.0/ui-ui.html. I think UI.setActiveView should do what you want.
Alternatively, you should be able to navigate using uri's like spotify:app:appname:tabname
disclaimer I haven't built any tabs into my app yet.