Our approach for extending Alfresco ADF applications

by / Friday, 26 January 2018 / Published in Blog
keensoft UST Global will be at MWC18
keensoft UST Global sponsors Technovation Challenge

This text aims to expose our humble experience extending alfresco-content-app, but first some context about motivations behind.

After the awesome DevCon event organized by Alfresco and the OrderOfTheBee this January in Lisbon,
there is still some buzzing going on about some of the challenges present in the current Alfresco ecosystem.

Personally I couldn’t attend the conference this year so I can’t wait for video recordings, fortunately you can easily find highlights of what’s going on in Alfresco at this moment, this are just some examples

A quick overview of Alfresco DevCon 2018 by Ángel Borroy

Alfresco DevCon 2018 wrap-up by David Webster

DevCon 2018 Retrospective by Nathan McMInn

One of the hottest topic, because is happening now, is the future of client applications on top of Alfresco. Alfresco Share has been the only and default client application shipped along with the distribution for years now, since version 3.2. I personally think Share is a great effort to have some content centric use case working fast, not only for collaborating, thanks to clear extension points, also suitable for many other scenarios.

Alfresco Development Framework (ADF) is growing fast and is consolidating as the Alfresco’s switch knife to create web applications that will fit any use case. Is more like building blocks to create only what you really need.

Explaining details of how to engage on this new ADF technologies is out of the scope of this text, you can find lot’s of nice articles on the Alfresco community site. There is also a dedicated gitter channel where you can find help directly from Alfresco engineers.

Ok… enough context, let’s focus on ADF

First of all, an exiting conversation/discussion is going on about this matter between Alfresco engineers and the Alfresco Community, after some twitter threats like this one started by Jeff, the conversation is now moving to Github.

Now our experience

Even though I couldn’t attend the DevCon, I did participate in the Hack-a-thon that took place during the conference, collaborating remotely with my team mate Tiago Simões, who was physically present on the hackers room. As a result, we published the Adding a new feature to Alfresco Content Application (ACA) project that was awarded by the Alfresco Community as “best ADF contribution of the year”, kind of proud, but let’s go down to details to found out that actually it was so simple.

Recently Alfresco published a first version of an example content application using ADF 2.0.0, aka alfresco-content-app. We used this application to renew one experiment that we did on the Global Hack-a-thon 2017 event, moving an actively used feature of Share to ADF. We choose “Edit on Ms Office” action because it’s a very simple action that most of our clients use.

This where the steps followed to create a feature module inside the application

$ git clone https://github.com/Alfresco/alfresco-content-app
$ cd alfresco-content-app
$ ng generate module modules/aos
$ ng generate service modules/aos/aos.editonline

This far, we got this files created on src/app/modules/aos. Feel free to chose another path.

aos.editonline.service.spec.ts
aos.editonline.service.ts
aos.module.ts

.spec.ts file is for unit testing, for example with Karma and Jasmine, this is also not cover by this text but you can find a lot of examples on ng2-alfresco-components source code.

This is the code for our aos.editonline.service.ts file, it was obviously inspired by the code present on Share source code to perform the action. We don’t put the content here trying not to extend the text too much, the point here is to show how this code actually runs inside the application.

This is the content of our feature module, quite simple as it is only providing our service.

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { AosEditOnlineService } from './aos.editonline.service';
@NgModule({
imports: [
CommonModule
],
declarations: [],
exports: [],
providers: [
AosEditOnlineService
] })
export class AosModule { }

Important thing here is that we are importing CommonModule from @angular/core to produce a feature module that can be then imported into the AppModule. We noticed that Alfresco ADF exposes a module called CoreModule that was used by the now old generator-ng2-alfresco-component yeoman generator project to create component modules. As the AOS action is so simple, we didn’t found this necessary but should be taken into account.

Next step is also simple, relatively import this module into the AppModule so it can by used by the application (src/app/app.module.ts)


import { AosModule } from 'modules/aos/aos.module';
...
@NgModule({
imports: [
...
AosModule
],
...

And use the module, so quick so easy.

In this case, we are following the ContentAction component extension point. At the time of our first tests, this seemed to be the right way to implement custom content actions (ADF 1.8.0), but ADF 2.0.0 comes with no one defined, instead crud operations on content are implemented as Directives on material buttons defined in the toolbar.

src/app/components/files/files.component.html


<adf-document-list #documentList
</data-columns>
<content-actions>
<content-action
icon="build"
target="document"
permission="update"
[disableWithNoPermission]="true"
(permissionEvent)="handlePermissionError($event)"
title="{{ACTION.AOS.TITLE | translate }}"
(success)="onContentActionSuccess($event)"
(execute)="aosEditonline($event)">
</content-action>
</content-actions>
</adf-document-list>

src/app/components/files/files.component.ts

import { AosEditOnlineService } from 'adf-aos-editonline-action';
constructor(
private aosEditOnlineService: AosEditOnlineService) {
}
aosEditonline(event) {
this.aosEditOnlineService.onActionEditOnlineAos(event.value.entry);
}

This makes the action available for all documents, to see how it works, watch the video we used to showcase the global Hack-a-thon 2017 project in the Office Hours: Hackaton demo event. You can also use the published npm module directly on your applications. Again, let’s get back to the point.

Publishing the module to npm registry

To finish the job and make this project pretend to be an addon we should be able to enable it on demand on any ADF application. In order to make our feature module available for other applications, we packaged and published the module on the npm registry using ng-packagr. Thanks to Denys Vuika for this tip during the hackathon event.

First we created the ng-package.json file to configure ng-packagr

{
"$schema": "./node_modules/ng-packagr/ng-package.schema.json",
"dest": "./dist/",
"lib": {
"entryFile": "public_api.ts",
"flatModuleFile": "adf-aos-action"
}
}

Next we created the public_api.ts file to define what’s going to be part of our library

export * from './index';

and contents of index.ts

export * from './aos.editonline.service';
export * from './aos.module';

At this point we got in trouble, ng-packagr needs to read a package.json file to process dependencies and so on. Looking to ADF source code, a good place to inspect a example of ng-packagr use, we finally decide to create a minimal package.json in the root of our module.


{
"name": "adf-aos-editonline-action",
"version": "2.0.1",
"author": "keensoft",
"description": "Alfresco ADF AOS action",
"repository": {
"type": "git",
"url": "https://github.com/keensoft/alfresco-content-app-with-aos/adf-aos-action"
},
"bugs": {
"url": "https://github.com/keensoft/alfresco-content-app-with-aos/issues"
},
"dependencies": {
"@alfresco/adf-content-services": "2.0.0",
"@alfresco/adf-core": "2.0.0",
"alfresco-js-api": "2.0.0"
},
"devDependencies": {
"ng-packagr": "^1.6.0"
},
"es2015": "adf-aos-action.js",
"keywords": [
"Alfresco",
"AOS",
"ADF"
],
"license": "GPL-3.0",
"main": "bundles/adf-aos-action.umd.js",
"metadata": "adf-aos-action.metadata.json",
"module": "adf-aos-action.es5.js",
"scripts": {
"package-aos": "ng-packagr -p ng-package.json"
},
"typings": "adf-aos-action.d.ts"
}

We think that the right thing will be to create the script package-aos on the alfresco-content-app package.json, but we couldn’t make it work.

With this package.json on place, we can now wrap our library and publish it to npm registry

$ npm run package-aos
$ npm login
$ npm publish dist

Finally, we configure the application to use the npm module published

Install the module on alfresco-content-app

npm install adf-aos-editonline-action@2.0.1

This will produce the following entry in the package.json, on dependencies section

"adf-aos-editonline-action": "2.0.1",

Change the import in the AppModule from relative path to the module name
src/app/app.module.ts

import { AosModule } from 'adf-aos-editonline-action';

Clean the alfresco-content-app project and build it again

$ mv src/app/modules/aos ~/adf_modules
$ npm run clean
$ npm install

Note that to build the application again, we moved our module out of the application.

Some notes

* The main problem we got is the maintenance of the module. After publishing it, it’s easy to use it on any application, but in order to upgrade the module and publish new versions, the module directory needs to be inside the alfresco-content-app, otherwise ng-packagr complains. We believe our np-packagr setup needs improvement to achieve total independence from alfresco-content-app.

* Other missing features

* Share comes with a SSO HTTP filter that has being our friend for years. Specially to integrate Alfresco based solutions on companies expecting SSO/SLO access to corporate applications. It pretty straight forward to integrate Alfresco and Share with many popular authentication mechanisms, not that much with CAS, but Ian Wright has done big efforts here to get the work done.

* Share Admin console along with javascript-console addon has done our life easier. On the other side, Alfresco admin console and Support Tools, is becoming also great.

* Share evaluators and indicators are both very good features that simplifies a lot most of the uses case implementations that we’ve faced.

* The Adding a new feature to Alfresco Content Application (ACA) project is also and example of how to deploy Alfresco based solutions on docker containers, component by component, without the installer.

Leave a Reply

TOP