SmartView Workflow extension
Hi
We have workflow extension that was working fine on CS version 20.3
var FormExtensionController = WorkItemExtensionController.extend({ type: 101, sub_type: 1, constructor: function (attributes, options) { WorkItemExtensionController.prototype.constructor.apply(this, arguments); options || (options = {}); this.context = attributes.context; }, validate: function (type, sub_type) { return true; }, execute: function (options) { var extensionPoint = options.extensionPoint; var deferred = $.Deferred(); if (extensionPoint === WorkItemExtensionController.ExtensionPoints.AddForm) { // CUSTOM CONTENT var WRContext = new PageContext(); var MCTileReportView = new TileReportView({ data: { title: 'Workflow WebReport Content', id: 222222, }, context: WRContext }); WRContext.fetch(); deferred.resolve({viewToShow: MCTileReportView}); return deferred.promise(); } else { } } }); return FormExtensionController; });
On 20.4 it does not work anymore, we get error "Ticket: Error getting ticket. Different user detected. Please reload the page to login again."
This seems to happen on context.fetch.
Any suggestion?
Comments
-
There were authentication changes recently in the framework which means you have to explicitly assign the session token to the PageContext. e.g.
var WRContext = new PageContext(), connector = WRContext.getObject(ConnectorFactory); // Pre-authenticate the default connector session connector.authenticator.updateAuthenticatedSession({ ticket: [LL_REPTAG_OTCSTICKET QUOTE /] });
The ConnectorFactory module path is 'csui/utils/contexts/factories/connector'.
Cheers
Ian
0 -
Thanks for the quick reply, Ian.
I tried it out. Error is gone, but I still can't get the WebReport to load
This is what I changed it
var WRContext = new PageContext(), connector = WRContext.getObject(ConnectorFactory); // Pre-authenticate the default connector session connector.authenticator.updateAuthenticatedSession({ ticket: options.model.connector.connection.session.ticket });
If I understood it correctly, I just took existing ticket from main model.
0 -
This is the example extension with static view that works just fine
execute: function (options) { var extensionPoint = options.extensionPoint; var deferred = $.Deferred(); if (extensionPoint === WorkItemExtensionController.ExtensionPoints.AddForm) { var MyLayout = Marionette.LayoutView.extend({ className: 'extensiontest-view', template: '<h4>This is the Text for ExtensionPoints Test</h4>', constructor: function MyLayout(options) { options || (options = {}); this.context = options.context; Marionette.LayoutView.prototype.constructor.apply(this, arguments); } }); var view = new MyLayout(); deferred.resolve({viewToShow: view}); return deferred.promise( ); } else { deferred.resolve({}); return deferred.promise(); } },
In version 20.3 also the WebReport View (the one I pasted first) worked.
0 -
Yes, this has been caused by a fix for security leak, that remained overseen for some time. If you create a new context, the connector that you will get using that context, will not be authenticated automatically:
var WRContext = new PageContext();
Such context will need an authentication to be useful for making server calls. Only the application page (or an authenticated REST call) can supply the initial authentication token. Both need to take place in back-end (OScript on CS), when a part of the script of the code is generated.
There are two ways how to get an authenticated context. The first one that you know from the Smart UI SDK development - you get it from the parent control. The parent control passes the context in options:
var MyView = Marionette.View.extend({ constructor MyView(options) { Marionette.View.call(thi, options) var context = options.context this.context = context ... }
Extensible views and controllers usually obtain the context like this and store it in the instance.
The second way is getting the authentication token on your own, when (and only if) you generate a part of your code in OScript, as Ian described it. If your extension does not get access to an authenticated context
If you extension point does not provide an authenticated context like this, it is worth filing a feature request for it. When your component runs on an already authenticated Smart UI page, you should not need to fetch the authentication token by your code.
0 -
Thanks for your reply, @Ferdinand Prantl !
I was able to get authenticated context already with the method that @Ian_Whitfield suggested. I don't get error anymore.
My remaining problem is that I'm not able to fetch and show WebReport view. Works if I try static view (as in documentation).
execute: function (options) { var extensionPoint = options.extensionPoint; var deferred = $.Deferred(); if (extensionPoint === WorkItemExtensionController.ExtensionPoints.AddForm) { // WebReport WRContext = new PageContext(), connector = WRContext.getObject(ConnectorFactory); // Pre-authenticate the default connector session connector.authenticator.updateAuthenticatedSession({ ticket: options.model.connector.connection.session.ticket }); var MCTileReportView = new TileReportView({ data: { title: 'Workflow WebReport Content', id: 222222, }, context: WRContext }); WRContext.fetch(); deferred.resolve({viewToShow: MCTileReportView}); return deferred.promise(); } else { } }
In earlier versions these 2 lines used to work - WebReport was fetched and shown. Not anymore in version 20.4
WRContext.fetch(); deferred.resolve({viewToShow: MCTileReportView});
Do you have any suggestion where it could be wrong?
Uldis
0 -
Your original code already fetched the data:
var MCTileReportView = new TileReportView({ data: { title: 'Workflow WebReport Content', id : 222222, }, context: WRContext }); // fetch the data, widget is supposed to re-render automatically WRContext.fetch(); deferred.resolve({viewToShow: MCTileReportView}); return deferred.promise();
Fetching the data on rendering is usually dangerous, because when the new data are obtained the widget usually re-renders:
MCTileReportView.on('render', function () { WRContext.fetch();
There could be a problem with TileReportView, which would not process the update events in each situation. You could try debugging what happens, once the data have been fetched and why the widget would not get updated. You can also try postponing the widget rendering until the data have been fetched:
var MCTileReportView = new TileReportView({ data: { title: 'Workflow WebReport Content', id : 222222, }, context: WRContext }); // return the widget after the data have been fetched return WRContext.fetch().then(function () { return { viewToShow: MCTileReportView }; });
0 -
The issues with 20.4 are probably related to the changes made to implement parameter prompting. The TileReportView now extends from the WidgetPromptWrapperView which is a Marionette 3 view and is used for all WebReport widgets that need to support prompting. It looks like there is an issue with performing the show after the fetch now as the WebReport output is lost when show is called.
I logged the following bug for this:
LLWR-15464: HTML WebReport widget fails to render correctly via the SDK if the view is shown after fetching the data
Ian
0 -
Thanks for your answer, @Ferdinand Prantl
The original code does not work in version 20.4. It did in 20.3. Something must have been changed since.
I tried postponing rendering as you suggested with
// return the widget after the data have been fetched return WRContext.fetch().then(function () { return { viewToShow: MCTileReportView }; });
Unfortunately it did not work like that.
Could I fetch data on other event (e.g. show). Would that make a difference?
0 -
Thanks for update @Ian_Whitfield
Maybe you have some workaround suggestion for version 20.4?
0 -
There might well be a workaround but I'd need to debug the issue in more detail first. We're in the middle of a release at the moment which means I'm not able to investigate this right now unfortunately. When things have calmed down a bit I'll try to see if there is a workaround for this and post an update here.
Cheers
Ian
1 -
@Uldis - I've looked into this now and have a fix that should be going into the next development update (21.4).
The main problem seems to be that the new wrapper view which handles parameter prompting defers instantiation of the main content view so the model is not added to the context any more when you call new TileReportView. This means when you call WRContext.fetch() it isn't fetching the WebReport content.
I think the simplest workaround for your specific case might be to add the model to the context manually before fetching. This should mean that the widget picks it up later when it's rendered.
WRContext.getModel(WRTextModelFactory, { attributes: { id: 222222, context: WRContext } }); WRContext.fetch();
The RequireJS module path for WRTextModelFactory above is 'webreports/utils/contexts/factories/wrtext.model.factory'.
Cheers
Ian
0 -
Thanks @Ian_Whitfield . I will try it out
0
Categories
- All Categories
- 123 Developer Announcements
- 54 Articles
- 150 General Questions
- 148 Thrust Services
- 57 OpenText Hackathon
- 37 Developer Tools
- 20.6K Analytics
- 4.2K AppWorks
- 9K Extended ECM
- 918 Core Messaging
- 84 Digital Asset Management
- 9.4K Documentum
- 32 eDOCS
- 186 Exstream
- 39.8K TeamSite
- 1.7K Web Experience Management
- 8 XM Fax
- Follow Categories