Environement
Framework : SAPUI5 V1.38.39
IDE : SAP WEB IDE
Problem
I want to use a SAPUI5 application in another one, in order to do so I found the following resource: https://blogs.sap.com/2017/04/05/sapui5-how-to-reuse-parts-of-a-sapui5-application-in-othermultiple-sapui5-applications/
Code from the app where I want to reuse another one
in component.js in init I used :
var sPath = sHostUrl.includes("webidetesting") ? "https://gtyext.net" : sHostUrl;
jQuery.sap.registerModulePath("ztntapp", `${sPath}/sap/bc/ui5_ui5/sap/ztntapp/`);
And in my view :
<core:ComponentContainer
name="ztntapp"
manifestFirst="true"
component="ztntapp">
</core:ComponentContainer>
and in neo-app.json
{
"path": "/sap/bc/ui5_ui5/sap/ztntapp/",
"target": {
"type": "destination",
"name": "gtyext_net",
"entryPath": "/sap/bc/ui5_ui5/sap/ztntapp/"
},
"description": "namespace.tntapp Resources"
}
Code from the reused app
in component.js
sap.ui.define([
"sap/ui/core/UIComponent",
"sap/ui/Device",
"./model/models"
], function (UIComponent, Device, models) {
"use strict";
return UIComponent.extend("TrackAndTrace.ztntapp.Component", {
metadata: {
manifest: "json"
},
init: function () {
[...]
},
[...]
});
});
in neo-app.json (it is the default one created via SAP WebIDE):
{
"welcomeFile": "/webapp/index.html",
"routes": [
{
"path": "/resources",
"target": {
"type": "service",
"name": "sapui5",
"entryPath": "/resources",
"version": "1.38.45"
},
"description": "SAPUI5 Resources"
},
{
"path": "/test-resources",
"target": {
"type": "service",
"name": "sapui5",
"entryPath": "/test-resources",
"version": "1.38.45"
},
"description": "SAPUI5 Resources"
},
{
"path": "/webapp/resources",
"target": {
"type": "service",
"name": "sapui5",
"entryPath": "/resources",
"version": "1.38.45"
},
"description": "SAPUI5 Resources"
},
{
"path": "/webapp/test-resources",
"target": {
"type": "service",
"name": "sapui5",
"entryPath": "/test-resources",
"version": "1.38.45"
},
"description": "SAPUI5 Test Resources"
}
],
"sendWelcomeFileRedirect": true
}
Error message
Uncaught Error: failed to load 'ztntapp/Component.js' from
https://webidetesting278-a392f.dispatcher.hana.ondemand.com/sap/bc/ui5_ui5/sap/ztntapp/Component.js:
Error: failed to load 'TrackAndTrace/ztntapp/model/models.js' from
resources/TrackAndTrace/ztntapp/model/models.js
Points with neo-app.json :
the application "ztntapp" itself works outside this application
the path for component.js is https://webidetesting278-a392f.dispatcher.hana.ondemand.com/sap/bc/ui5_ui5/sap/ztntapp/Component.js however the path for model somehow become https://webidetesting278-a392f.dispatcher.hana.ondemand.com/webapp/resources/TrackAndTrace/ztntapp/model/models.js (I am not sure why "webapp/resources")
https://webidetesting278-a392f.dispatcher.hana.ondemand.com/sap/bc/ui5_ui5/sap/ztntapp/model/models.js is found, resource should probably be loaded from here instead of /webapp/resources/TrackAndTrace/ but I don't know how to do so
Other research
With the neo-app.json file, the problem is to locate the resource
from the "ztntapp", I seen that there is also a
jQuery.sap.registerResourcePath but I am not sure how to use it for
this case
In your first application (main app) please use manifest.json to add the component usage instead of jQuery.sap.registerModulePath in Component.js:
"componentUsages": {
"ztntapp": {
"name": " TrackAndTrace.ztntapp",
"settings": {},
"componentData": {},
"lazy": true
}
}
Then you need to adjust your main app neo-app.json to enable Run configuration to reach your second app (reuse app)
"routes": [
{
"path": "/webapp/resources/TrackAndTrace/ztntapp",
"target": {
"type": "application",
"name": "ztntapp"
}
},
{
"path": "/resources/TrackAndTrace/ztntapp",
"target": {
"type": "application",
"name": "ztntapp"
}
},
Then for the resue app: Deploy your app, so it becomes registered within the SAP WebIDE Fullstack workspace.
Then for your main app in WebIDE, chose Run > Run Configurations > Add configuration > Run as Web Application > Advanced Settings mark Use my workspace first and then press Get Resource Versions. On the list below, you should see your reuse app listed under Resources Name:
Try with this :
jQuery.sap.registerModulePath("ztntapp", "/sap/bc/ui5_ui5/sap/ztntapp")
instead of
jQuery.sap.registerModulePath("ztntapp", ${sPath}/sap/bc/ui5_ui5/sap/ztntapp/)
Also check this link :
https://answers.sap.com/questions/668485/ui5-failed-to-load-componentjs-while-using-compone.html
Related
I'm pretty new in SAPUI5 and started to learn the subject on Routing and navigation as you can see in their documentation:
https://ui5.sap.com/#/topic/e5200ee755f344c8aef8efcbab3308fb
Now I did all the changes like they do in their documentation but I have an error that I don't understand why it is being thrown:
The target overview no viewName defined. - EventProvider sap.m.routing.Target
Here is the manifest:
{
"...": "...",
"sap.ui5": {
"_version": "1.1.0",
"resources": {
"css": [
{
"uri": "css/style.css"
}
]
},
"dependencies": {
"minUI5Version": "1.60",
"libs": {
"sap.m": {}
}
},
"...": "...",
"rootView": {
"viewName": "sap.ui.startApp.view.App",
"type": "XML",
"async": true,
"id": "app"
},
"routing": {
"config": {
"routerClass": "sap.m.routing.Router",
"type": "View",
"viewType": "XML",
"path": "sap.ui.startApp.view",
"controlId": "app",
"controlAggregation": "pages"
},
"routes": [
{
"pattern": "",
"name": "overview",
"target": "overview"
},
{
"pattern": "detail",
"name": "detail",
"target": "detail"
}
],
"targets": {
"overview": {
"id": "overview",
"name": "Overview"
},
"detail": {
"id": "detail",
"name": "Detail"
}
}
}
}
}
Solution
Either add "async": true to /sap.ui5/routing/config/ in manifest.json
Or preferably add "sap.ui.core.IAsyncContentCreation" to the application's UIComponent:
sap.ui.define([
"sap/ui/core/UIComponent",
// ...
], function(UIComponent/*,...*/) {
"use strict";
return UIComponent.extend("my.Component", {
metadata: {
interfaces: [
"sap.ui.core.IAsyncContentCreation", // Available since 1.89.0
],
manifest: "json",
},
// ...
});
});
Analysis
The /sap.ui5/routing/targets properties viewName, viewId, viewPath, and viewLevel are regarded as legacy syntax since UI5 1.58.0 (as part of the initiative to support routing with nested components) and thus it is correct to declare name, id, path, and level respectively instead of viewName, etc.. *
The error "[...] no viewName defined" actually comes from sap/ui/core/routing/sync/Target.js. The /sync part indicates that the views are created synchronously which should be avoided because it's blocking the UI thread of the browser during the routing process. Instead, targets should be created asynchronously which, however, requires an additional flag as shown above.
If the targets are created asynchronously, the error will be gone.
* In case existing apps still need to migrate to the new name, id, path, and level syntax:
Add:
"type": "View" to /sap.ui5/routing/config/ (Cf. commit: ef476f1)
"minUI5Version": "1.98.0" or higher to /sap.ui5/dependencies/ (Cf. commit: 867496d)
The property /sap.ui5/rootView/viewName is not affected.
Related discussion: https://github.com/SAP/openui5/issues/3417
We have a self-hosted Azure DevOps Server 2019 for which I have created my own widget using the tutorial https://learn.microsoft.com/en-us/azure/devops/extend/develop/add-dashboard-widget?view=azure-devops-2019.
I was also able to successfully add the extension to the server and the extension is also visible.
However, when I edit my dashboard, my newly created widget is not displayed. What could be the reason for this?
Furthermore, I also installed the extension VstsDashboardWidgetProjectTemplate (https://github.com/GregTrevellick/VstsDashboardWidgetProjectTemplate) in Visual Studio and also created an extension/widget from it. Unfortunately with the same result that I can install and see the extension, but not the actual widget.
I am attaching the vss-extension.json file as I suspect this is where the error is most likely to be found. However, I can also supply the other files if needed.
{
"manifestVersion": 1,
"id": "MyVeryFirstCustomExtension",
"version": "1.0.0",
"name": "My Very First Custom Extension",
"description": "Samples containing different widgets extending dashboards",
"publisher": "MyCompany",
"categories": [
"Azure Boards"
],
"targets": [
{
"id": "Microsoft.VisualStudio.Services"
}
],
"icons": {
"default": "img/logo.png"
},
"contributions": [
{
"id": "HelloWorldWidget",
"type": "ms.vss-dashboards-web.widget",
"targets": [
"ms.vss-dashboards-web.widget-catalog"
],
"properties": {
"name": "Hello World Widget",
"description": "My first widget",
"catalogIconUrl": "img/CatalogIcon.png",
"previewImageUrl": "img/preview.png",
"uri": "hello-world.html",
"supportedSizes": [
{
"rowSpan": 1,
"columnSpan": 2
}
],
"supportedScopes": [
"project_team"
]
}
}
],
"files": [
{
"path": "hello-world.html",
"addressable": true
},
{
"path": "sdk/scripts",
"addressable": true
},
{
"path": "img",
"addressable": true
}
],
"scopes": [
"vso.work"
]
}
Please help to read the configuration values from the configuration contribution point. In the ${extension_path}\package.json I how following section:
{
"name": "markdown-table-of-contents",
"displayName": "Generate table of contents for markdown",
"publisher": "dkultasev",
"description": "",
"version": "0.0.1",
"engines": {
"vscode": "^1.31.0"
},
"categories": [
"Other"
],
"activationEvents": [
"onCommand:extension.sqlGenerateYAMLComment"
],
"main": "./out/extension.js",
"contributes": {
"configuration": {
"title": "Default name to use for YAML comment block",
"properties": {
"markdown-table-of-contents.author_name": {
"type": [
"string",
"Change Name"
],
"default": null,
"description": "Specify default name when generating YAML comment block"
}
}
}
...
then in the extension_folder\.vscode\settings.json I have setting "markdown-table-of-contents.author_name": "Dmitrij Kultasev" and in the extension code I'm trying to get these values:
const name = vscode.workspace.getConfiguration('markdown-table-of-contents').get('author_name');
and it is Change Name but I expect Dmitrij Kultasev as configured in settings.json file
I have tried adding bootstrap css to the install.json file the following way, but I got an error:
,
{
"type": "style",
"src": "https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css"
}
How can I add it to the project and use it?
I tested this in my install.json and it worked fine
"resources": {
"body": [
{
"type": "style",
"src": "https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css"
},
{
"type": "style",
"src": "./source/app.css"
},
{
"type": "script",
"src": "./source/app.js"
}
]
},
"preview": {
"handlers": [
{
"options": ["_default"],
"execute": "INSTALL_SCOPE.setOptions(INSTALL_OPTIONS)"
},
{
"options": ["_product"],
"execute": "INSTALL_SCOPE.setProduct(INSTALL_PRODUCT)"
}
]
},
"options": {}
}
There is likely something wrong with the JSON of your install.json. You could try copy and paste your install.json in this tool to test: https://www.cloudflare.com/apps/developer/install-json-tester
I am looking for a way to write initial settings to settings.json for when my extension is installed.
I found WorkspaceConfiguration API, but that seems to retrieving/updating values at runtime.
I'm looking to get my settings + comments into the default settings file
e.g. How TSLint does it:
I hope I get your question correctly: I assume you mean the User Settings settings.json you can get via File>Preferences>User Settings.
If you know that TSLint does it, you can go to your extensions folder (windows: $USERFOLDER/.vscode/extensions), pick the extension (in my case it was the folder "eg2.tslint-0.6.7") and peek the files.
...
"contributes": {
"configuration": {
"type": "object",
"title": "TSLint",
"properties": {
"tslint.enable": {
"type": "boolean",
"default": true,
"description": "Control whether tslint is enabled for TypeScript files or not."
},
"tslint.rulesDirectory": {
"type": [
"string",
"array"
],
"items": {
"type": "string"
},
"description": "An additional rules directory",
"default": ""
},
"tslint.validateWithDefaultConfig": {
"type": "boolean",
"description": "Validate a file when there is only a default tslint configuration is found",
"default": false
},
"tslint.configFile": {
"type": "string",
"description": "The path to the rules configuration file",
"default": ""
},
"tslint.ignoreDefinitionFiles": {
"type": "boolean",
"default": true,
"description": "Control if TypeScript definition files should be ignored"
},
"tslint.exclude": {
"type": [
"string",
"array"
],
"items": {
"type": "string"
},
"description": "Configure glob patterns of file paths to exclude from linting"
},
"tslint.run": {
"type": "string",
"enum": [
"onSave",
"onType"
],
"default": "onType",
"description": "Run the linter on save (onSave) or on type (onType)"
},
"tslint.nodePath": {
"type": "string",
"default": "",
"description": "A path added to NODE_PATH when resolving the tslint module."
},
"tslint.autoFixOnSave": {
"type": "boolean",
"default": false,
"description": "Turns auto fix on save on or off."
}
}
}
...
Hope this helps