This afternoon I saw a Tweet asking if there were any examples of how to use the AlfDocumentPreview widget. Aikau documentation is currently very thin on the ground (as you're probably no doubt painfully aware) so I thought it would be worth writing up a quick blog post to describe how we use it and how you can too. If there's anything that you want more information on then it's worth Tweeting me @_DaveDraper with a request - I can't guarantee that I'll be able to write it up as a blog post, but I will try to do my best as my time allows!
Most of the Aikau widgets are completely new, some are 'shims' around existing YUI2 based code and a few are direct ports of YUI2 widgets. The AlfDocumentPreview widget (and it's associated plugins) is a good example of a ported widget. The original code was copied into an Aikau widget definition and then most of the YUI2 code was replaced, bugs were fixed and thorough JSLinting applied.
You might wonder why we'd go to such lengths when a widget already existed. This essentially gets right to one of the fundamental points of Aikau as a framework. The code inside the widget really isn't important - what's important is defining an interface to a widget that performs a single specific task that can be referenced in a declarative model. The widget becomes an API to a piece of UI functionality - in this case, previewing a widget.
Every Aikau page model that references it will never need to change - even if we decide to completely rewrite the widget to use JQuery, Angular, Web Components or whatever happens to be the current flavour of the month - the pages will function as they always have.
The rule of thumb that I tell anyone asks me, is that if Alfresco has used an Aikau widget in a product feature then it's fair game for use in your application or extension. There are a number of widgets that are definitely beta quality (and we call these out in the JSDoc) which might be subject to change, but once it's been used in a feature then we're obliged to maintain backwards compatibility and fix any bugs with it.
The AlfDocumentPreview is currently being used in the new filtered search feature that is part of the 5.0 release (and you'll also find it used in the Film Strip View that is part of the prototype Aikau based Document Library which is not yet a product feature!). If you click on the thumbnail of any document (that is not an image) then a new dialog is opened that contains a preview of that document. The preview will render the appropriate plugin (e.g. PDF.js, video, audio, etc) for the content type.
Each row in the search results is an AlfSearchResult widget that contains a SearchThumbnail widget. When you click on the thumbnail widget (of the appropriate type) then a payload is published on the 'ALF_CREATE_DIALOG_REQUEST' topic to which the AlfDialogService subscribes. The payload contains a JSON model of widgets to render in the dialog when it is displayed. The model is an AlfDocument widget that contains an AlfDocumentPreview widget.
...
widgetsContent: [
{
name: 'alfresco/documentlibrary/AlfDocument',
config: {
widgets: [
{
name: 'alfresco/preview/AlfDocumentPreview'
}
]
}
}
],
...
The point of the AlfDocument widget is to ensure that all of the relevant Node data is available to pass to a child widget (in this case the AlfDocumentPreview - but it could be something else) so to do something with.
One of the key things about the search page is that search requests only return a very limited amount of data about each node (unlike requests from the Document Library which are slower but contain much more information such as all the properties and the actions permitted for the current user).
An additional XHR request is required to obtain all the data required to preview the node. The payload published when clicking on the thumbnail also contains the publication to make once the dialog has been displayed:
...
publishOnShow: [
{
publishTopic: 'ALF_RETRIEVE_SINGLE_DOCUMENT_REQUEST',
publishPayload: {
nodeRef: this.currentItem.nodeRef
}
}
]
...
The 'ALF_RETRIEVE_SINGLE_DOCUMENT_REQUEST' is serviced by the DocumentService and the AlfDocument subscribes to successful document loaded publications (note that the SearchThumbnail will have a 'currentItem' attribute set containing the limited data returned by the search request which will contain a 'nodeRef' attribute).
The AlfDocument only processes it's child widgets once it has some data about a specific node. Once the DocumentService has published the node data then it will process the AlfDocumentPreview widget. From that point on the AlfDocumentPreview will use the data that has been provided to create the appropriate plugin to preview the document.
You don't have to use an AlfDocumentPreview within an AlfDocument, you just need to ensure that you provide it with node data as the 'currentItem' configuration attribute. So if you already have the all the data (for example if you've made a request from within your JavaScript controller or if you are accessing it from a list that has been generated from the REST API used to service the Document Library) then you can configure it into the widget directly.
The following is an example of a simple Aikau page model that previews a document (obviously you need to swap in your own nodeRef!):
model.jsonModel = {
services: ['alfresco/services/DocumentService'],
widgets: [
{
name: 'alfresco/documentlibrary/AlfDocument',
config: {
nodeRef: 'workspace://SpacesStore/7d829b79-c9ba-4bce-a4df-7563c107c599',
widgets: [
{
name: 'alfresco/preview/AlfDocumentPreview'
}
]
}
}
]
};
You also don't need to display it in a dialog either.
Once again this should hopefully demonstrate how you can re-use Aikau widgets to achieve very specific objectives - try doing using the YUI2 previewer in isolation and then you'll understand why it's been ported!
Hopefully this has provided both a useful description of how we're currently using the AlfDocumentPreview widget (as well as how we've configured pub/sub in the filtered page to link widgets and services). If anything isn't clear or you have further questions then please comment below.