Nested Vaadin applications - java

Is it possible to nest one Vaadin application into another? I want to implement a portal with application A and embed several applications into that portal.
I can have multiple Vaadin applications next to each other by calling vaadin.initApplication multiple times with different IDs as target elements:
vaadin.initApplication("target-element-id",{
"theme": "mytheme",
"versionInfo": {
"vaadinVersion": "7.5.1",
"atmosphereVersion": "2.2.7.vaadin1"
},
"widgetset": "de.test.widgetset",
"vaadinDir": "http://localhost/VAADIN/",
"browserDetailsUrl": "http://localhost/service1",
"serviceUrl": "http://localhost/service1",
"debug": true,
"standalone": false,
"heartbeatInterval": 300
});
But as soon as I specify an element as target that is already inside a Vaadin UI, I get the following error:
java.lang.AssertionError: A widget that has an existing parent widget may not be added to the detach list

Sounds like you want a Vaadin application as a portlet. The Vaadin docs contain a chapter for that: https://vaadin.com/docs/-/part/framework/portal/portal-overview.html
Information on Java portlets:
https://en.wikipedia.org/wiki/Java_Portlet_Specification
You may have a look at Liferay:
https://en.wikipedia.org/wiki/Liferay

Related

Get Android Paging 3.0 with RxJava working in Java (not Kotlin)

I managed to get Paging library 3.0.0-alpha02 working with RxJava2 in a Kotlin app, following the Paging 3 documentation.
However I had a problem when I ported the paging code to a Java app, in that the data is being retrieved by page, but the page retrieval keeps happening in the background even when I don't scroll the recyclerview. In other words, after loading page 1, it then loads page 2, 3, 4, etc, and keeps going.
I'm setting up the paging in the viewmodel:
public Observable<PagingData<Item>> loadItems()
{
PagingConfig config = new PagingConfig(...);
Pager<Integer, Message> pager = new Pager<Integer, Item>(config, null, null,
() -> new MyPagingSource());
return PagingRx.getObservable(pager)
}
Then subscribe in the activity/fragment:
disposable = viewModel.loadItems()
.subscribe( pagingData -> {
getAdapter().submitData(getLifecycle(), pagingData);
});
In the Java app, I'm subscribing in a fragment instead of and an activity, but otherwise the code is the same as the Kotlin app.
I realize that the paging library 3 uses coroutines and flow internally, so I added this dependency but it didn't make any difference.
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-rx2:1.3.7'
Edit:
The Kotlin demo app is on GitHub and has a RxJava as well as a Flow version (based on the Android samples). It does paging on the Telephony content provider to get SMS inbox messages.
PagingSource.load is automatically triggered based on PagingConfig.prefetchDistance as items are bound to RecyclerView. This means that even if you don't scroll, Paging will try to fulfill items based on visible viewport.
Terminating load behaves the same regardless of what language you're using, but it is based on prev/nextKey being null for LoadResult.Page in PagingSource and endOfPaginationReached in RemoteMediator.
If you believe that this is an issue with the library, I'd encourage you to file an issue here: https://issuetracker.google.com/issues/new?component=413106&template=1096385 with an attached repro, and I'd be happy to take a look!
Otherwise if you could attach your PagingSource implementation, that would help as there isn't much information to go on with what you've posted so far.
It turns out that Paging 3.0 with RxJava does work properly, when it is being used in an activity. I have the problem because I had the recyclerview, adapter, etc in a fragment. Not sure why this is, possibly due to differences in the lifecycle?

How to add Cards to microsoft teams bot using Bot Framework SDK for Java?

I'm using the Java botbuilder to build a microsoft teams bot. I want to add Cards to my bot (e.g. to embed links, quick replies, and images).
In the above link it says: suggested actions are not supported in Microsoft Teams: if you want buttons to appear on a Teams bot message, use a card.
However, I can find no documentation on how to add a 'card' to the Activity schema.
I tried:
1. Using suggested actions
I tried adding my List<CardAction> to the SuggestedActions
field in Activity but they were not rendered by microsoft teams
(as expected, the documentation says this is not supported).
2. Using Attachments
I suspect it could be done using attachments, but can only find
documentation for the C#/JS versions (e.g.
https://learn.microsoft.com/en-us/azure/bot-service/nodejs/bot-builder-nodejs-send-rich-cards?view=azure-bot-service-3.0).
So I want to know how to add 'a card' to Activity schema so it can be rendered by my bot.
The BotFramework Java SDK is still in preview, so there isn't a lot of documentation I can point you towards. However, here is an example of adding a HeroCard to a reply.
Activity reply = new Activity()
.withType(ActivityTypes.MESSAGE)
.withRecipient(activity.from())
.withFrom(activity.recipient())
.withAttachments(Arrays.asList(
new Attachment()
.withContentType("application/vnd.microsoft.card.hero")
.withContent(new HeroCard()
.withTitle("Hero Card")
.withSubtitle("BotFramework")
.withButtons(Arrays.asList(new CardAction()
.withValue("https://learn.microsoft.com/en-us/azure/bot-service/")
.withTitle("Get started")
.withType(ActionTypes.OPEN_URL)
))
.withImages(Collections.singletonList(new CardImage()
.withUrl("https://sec.ch9.ms/ch9/7ff5/e07cfef0-aa3b-40bb-9baa-7c9ef8ff7ff5/buildreactionbotframework_960.jpg"))))
));
You can also take a look at the SDK Attachment Tests for more examples.
Hope this helps!

How to redirect user from root node to it's child node in Magnolia CMS

My project is developed using Magnolia 5.3 and Blossom and is using Enterprise Edition - Standard version of magnolia.
I am new for Magnolia and this project.
This project is for different countries and in different languages.
It has the first page for the country and language listing.
For ex. www.localhost:8080 shows this country listing page.
When user clicks on any link of this page, then he is redirected to country home page with chosen language.
For Example:
Country C1 with language L1 has the URL: www.localhost:8080/C1/L1
And this shows the content of country root page i.e. C1
Each country has the same heirarchy in Magnolia CMS
C1 - Root Node of country C1
C1/XYZ1 - Page 1
C1/XYZ2 - Page 2
C2 - Root Node of country C2
C2/XYZ1 - Page 1
C2/XYZ2 - Page 2
and so on.
So if I want to access any root page of country then URL will be:
www.localhost:8080/C1/L1
And If I want to access any child page then URL will be:
www.localhost:8080/C1/L1/XYZ1
This is fine so far.
But now I want to remove or hide the country root page from the user.
So If user manually type www.localhost:8080/C1/L1 then
User should be warn with no page found or
User is redirected to page1 i.e. www.localhost:8080/C1/L1/XYZ1 and show page1 content.
I have tried with setting virtualURIMapping but this do not work.
I also tried to remove C1 page but I can not remove as this is the root page and it is not possible to remove root without it's children.
Please help and guide me, how can I do this?
Thanks,
Manoj
If you are using Enterprise version, all you have to do is configure domain for your site to have it recognized properly and then Magnolia will hide root node automatically from all links.
If you are using Community edition, it's not possible as this feature is only in Enterprise.
However if you instead want to redirect to a subpage of the selected site (as it seems to now after your update of the question), you need to create a virtual URI mapping to do this.
There are many possible ways to create such mapping, one of them would be:
1) in AdminCentral, go to Configuration app and open config:/modules/ui-admincentral/virtualURIMapping\default
2) change class to info.magnolia.multisite.MultiSiteRegexpVirtualURIMapping
3) change fromURI to \$
4) change toUri to redirect:/XYZ1\.html
5) add property site and set it's value to C1 (assuming your site in WebDev/Sites is called C1)
This will work only if you have your domains mapped properly in the site configuration. If you don't get it working on the first try, try to play with it, change the values, double check you have all config correctly. Try to maybe also look in the code of the mapping to make sure you understand how it work. And most importantly, check other VirtualURIMappings you have configured (you can see all in Config Info app).
Additional disclaimer: If you set virtual uri mapping incorrectly (specially since this one is regex based so it is super easy to "expand" it to react on all urls), it is possible to make your instance inaccessible. Make sure when you do this, you do so on your development instance and that you have backup and can go back. Only apply such change on production via importing previously created and tested mapping.
HTH,
Jan

How to load non model data in ExtJS viewmodel?

We've been slowly getting accustomed to ExtJS and we recently started using view models to bind data to our form panels. In general we are trying to keep our ExtJS models consistent with our backend java models, and any conversion required is done via view model formulas. When viewing general data this works perfectly however when we want to show more specific data that don't really exist in any kind of model, we are not sure how to approach their loading and creation in the client. For example:
I have a folder model with id and description properties. When loading a folder model via a read request the model loads the description from the database etc. Same thing with a User model. Two properties id and username. My question is, what if I have a form panel where I show the user and his associated folder. As far as the database layer is concerned, there is a 1:1 table where a user id is connected to a folder id to match the user and his personal folder. However we do not have this information available in any of the models. There is a specific service called getUserFolder which returns a folder object for the specific user id given. How should I put this in my panel's view model and how do I tackle the loading process?
Should I create a new model representing the table and use a get request to get the association, then use formulas to get the matched folder id for the given user? Should I just use a normal Ext.Ajax.request to get a folder id and then load the folder model? Should I create a general service that returns all the data (user and folder) and then match them in the client side on the request callback via setData of both models? What is the best practice?
TL;DR: Loading model data in viewmodels works fine but how to tackle loading non-model data in view models? They are only required in specific scenarios and are not included in the model's creation.
Your task has very little to do with view. It's all model, data model :) There is a concept of associations in ExtJS, including the 1:1 scenario. So I'd recommend to look into it.
Data binding and the ViewModel that powers it are powerful additions to Ext JS.
Ext.create('Ext.panel.Panel', {
title: 'Simple Form',
viewModel: {
type: 'test'
},
layout: 'form',
defaultType: 'textfield',
items: [{
fieldLabel: 'First Name',
bind: '{firstName}' // uses "test" ViewModel from parent
},{
fieldLabel: 'Last Name',
bind: '{lastName}'
}]
});

GWT inter project communication

We have a large GWT project and many smaller GWT sub-projects
basically the large controller project invokes the smaller projects
via many means such as some are incorporated into iframes that are shown in page,
some are shown by clicking a URL and opening the project into a new window.
The requirement is to change the Css on the fly, this is possible in the main project,
by simply changing, on the fly, the href of the link tag containing stylesheet url
is it possible to propogate this change to the sub-projects too ?
or asking in more broader terms,
how do i achieve inter - project communication in GWT ?
A browse allows you to call Javascript code across IFrames if the domains of the different GWT applications are the same.
Using JSNI you can register methods on the window object which call back into the GWT application and using JSNI the other project can invoke this method.
If all the apps are served from the same domain you could store the name of the stylesheet in a cookie. Each app would then use the cookie to select the appropriate stylesheet.
String theme = Cookies.getCookie("THEME");
if (theme == null) {
theme = "default";
}
Element e = DOM.createElement("link");
DOM.setElementProperty(e, "rel", "stylesheet");
DOM.setElementProperty(e, "href", GWT.getModuleBaseURL() + currentTheme +
".css");
DOM.appendChild(getHead(), e);
private native Element getHead() /*-{
return $doc.getElementsByTagName('head')[0];
}-*/;

Categories