How to update ADF from version 1.9.0 to 2.0.0

Document created by eugenio_romano Employee on Dec 7, 2017Last modified by eugenio_romano Employee on Dec 12, 2017
Version 15Show Document
  • View in full screen mode

In this Tutorial, I would like to help you to update your project created with the ADF Yeoman app generator. Many people have asked on our gitterchannel which are the correct steps to upgrade from version 1.9.0 to version 2.0.0

In order to understand the possible ways to update a project I did some different experiments with old projects and I finally find out the following two different approaches:

  1. Automatic update of the project using the Yeoman Generator.

  2. Manually update the project.

If you are not using a versioning system on your project I suggest you to execute backup copy of it before to following one of this approach. 

           

A. Automatic update of the project using the Yeoman Generator

If your application is mainly just the output of the generated app, you can try to follow those steps:

  • Update the Yeoman generator to version 2.0.0
npm uninstall -g generator-ng2-alfresco-app
npm install -g generator-ng2-alfresco-app

 

  • Run the new yeoman app generator.
yo ng2-alfresco-app

 

  • Clean your old distribution and dependencies.
npm run clean

 

  • Install the dependencies.
npm install

 

At this point, the generator could have maybe overwritten some of your changes. Remember to check the differences with the original source code (this is one of the reasons you should use a versioning system) and, if this is the case, retrofit the changes. Once done, it's time to start the application using the npm run startcommand.

After starting the app, if everything is working fine, that's all and you don't need to do anything else. On the contrary, if you have bugs and nothing really work, recover the original version of the project and try the manual approach.   

           

B. Manually update the project 

Considering that a project generated using the scaffolder is probably customised, its automatic update could not be an option. The following method is more surgical and would request a bit of elbow grease. As an example, I created a new project with the Yeoman generator version 1.9.0 You can find this example in the folder belonging to the 2.0.0 update in the ADF examplesrepo. As you can see, each commit represents a separate step in the upgrade process, which I now describe one by one.

1. Generation of an ADF project using the app generator

Nothing to describe here. In case of our planned modifications, you should have a similar project.

 

2. Update the project using the ADF prefix updater

The ADF prefix updater is going to update automatically all the following problems:

  1. Change all alfresco- activiti- old prefix with adf-
  2. Change all md- old prefix with mat- prefix
  3. Change all the old import with the new import for more details give a look to the last section
  4. Change all the old class name with the new class name 
  5. Change all the old type using the new types

 

Install the ADF prefix updater 

npm i -g adf-prefix-updater

Run the tool to update the material prefixes : 

adf-switcher -p tsconfig.json

 

3. Update polyfills file

Substitute the content of your app/polyfills.ts:

/* tslint:disable */

import 'core-js/es6/symbol';
import 'core-js/es6/object';
import 'core-js/es6/function';
import 'core-js/es6/parse-int';
import 'core-js/es6/parse-float';
import 'core-js/es6/number';
import 'core-js/es6/math';
import 'core-js/es6/string';
import 'core-js/es6/date';
import 'core-js/es6/array';
import 'core-js/es6/regexp';
import 'core-js/es6/map';
import 'core-js/es6/set';
import 'classlist.js';
import 'web-animations-js';
import 'core-js/es6/reflect';
import 'core-js/es7/reflect';
import 'core-js/es6/array';
import 'core-js/es7/array';
import 'web-animations-js';
import 'zone.js/dist/zone';
import 'intl';
import 'custom-event-polyfill/custom-event-polyfill';

4. Update vendor file

Substitute the content of your app/vendor.ts:

/* tslint:disable */

// Angular
import '@angular/common';
import '@angular/core';
import '@angular/http';
import '@angular/platform-browser';
import '@angular/platform-browser-dynamic';
import '@angular/router';

// RxJS
import 'rxjs';

// hammerjs
import 'hammerjs';

// Alfresco
import 'alfresco-js-api';
import '@alfresco/adf-core';
import '@alfresco/adf-content-services';
import '@alfresco/adf-process-services';
import '@alfresco/adf-insights';

import 'chart.js';
import 'ng2-charts';
require('script-loader!raphael/raphael.min.js');

require('script-loader!moment/min/moment.min.js');

require('pdfjs-dist/web/compatibility.js');

// Setting worker path to worker bundle.
let pdfjsLib = require('pdfjs-dist');
pdfjsLib.PDFJS.workerSrc = 'pdf.worker.js';

require('pdfjs-dist/web/pdf_viewer.js');

5. Update the custom styles file

Substitute the custom theme in your app/theme.scss:

@import './components/app-layout/app-layout.component.scss';

@import '~@alfresco/adf-content-services/theming';
@import '~@alfresco/adf-process-services/theming';
@import '~@alfresco/adf-insights/theming';
@import '~@alfresco/adf-core/theming';

@import '~@angular/material/theming';

@include mat-core($alfresco-typography);

$primary: mat-palette($alfresco-accent-orange);
$accent:  mat-palette($alfresco-accent-purple);
$warn:    mat-palette($alfresco-warn);
$theme:   mat-light-theme($primary, $accent, $warn);

@include angular-material-theme($theme);
@include adf-app-layout-theme($theme);

@include adf-content-services-theme($theme);
@include adf-process-services-theme($theme);
@include adf-insights-theme($theme);
@include adf-core-theme($theme);

body, html {
    margin: 0;
    height: 100%;
    overflow: hidden;
    font-size: mat-font-size($alfresco-typography, body-1);
    font-family: mat-font-family($alfresco-typography);
    line-height: mat-line-height($alfresco-typography, body-1);
}

body {
    overflow: auto;
}

 

6. Update package.json external library

In 2.0.0 we have updated most of the library and also changed the name of our packages. Read the release note to have more details about it.

Substitute the dependencies in your package.json:

"dependencies": {
    "@angular/animations": "5.0.5",
    "@angular/cdk": "5.0.0",
    "@angular/common": "5.0.5",
    "@angular/compiler": "5.0.5",
    "@angular/core": "5.0.5",
    "@angular/flex-layout": "2.0.0-beta.10",
    "@angular/forms": "5.0.5",
    "@angular/http": "5.0.5",
    "@angular/material": "5.0.0",
    "@angular/platform-browser": "5.0.5",
    "@angular/platform-browser-dynamic": "5.0.5",
    "@angular/router": "5.0.5",
    "@ngx-translate/core": "8.0.0",
    "alfresco-js-api": "2.0.0",
    "@alfresco/adf-content-services": "2.0.0",
    "@alfresco/adf-process-services": "2.0.0",
    "@alfresco/adf-core": "2.0.0",
    "@alfresco/adf-insights": "2.0.1",
    "chart.js": "2.5.0",
    "classlist.js": "1.1.20150312",
    "core-js": "2.4.1",
    "custom-event-polyfill": "0.3.0",
    "hammerjs": "2.0.8",
    "intl": "1.2.5",
    "minimatch": "3.0.4",
    "moment": "2.18.1",
    "moment-es6": "^1.0.0",
    "ng2-charts": "1.6.0",
    "pdfjs-dist": "1.5.404",
    "raphael": "2.2.7",
    "reflect-metadata": "0.1.10",
    "rxjs": "5.5.2",
    "web-animations-js": "2.3.1",
    "zone.js": "0.8.14"
},

7. Fix the custom-editor.component.ts

You can simplify the  app/components/acticiviti/custom-editor/custom-editor.component.ts you need manually to update the import because of the disble tlsint rule:

Change the import from:

import { WidgetComponent } from 'ng2-activiti-form';

to:

import { WidgetComponent } from '@alfresco/adf-core';

8. Fix the theme picker

Open the  app/components/theme-picker/theme-picker.html and change the template:

<button mat-icon-button [mat-menu-trigger-for]="themeMenu" matTooltip="Select a theme!">
<mat-icon>format_color_fill</mat-icon>
</button>

<mat-menu class="docs-theme-picker-menu" #themeMenu="matMenu" x-position="before">
<button *ngFor="let theme of themes" mat-menu-item (click)="installTheme(theme)" >
<mat-icon mat-list-icon [matTooltip]="theme.name" class="docs-theme-chosen-icon" [style.color]="theme.accent"
[style.background]="theme.primary"
*ngIf="currentTheme === theme">
check_circle
</mat-icon>
<mat-icon mat-list-icon [matTooltip]="theme.name" class="docs-theme-chosen-icon" [style.color]="theme.accent"
[style.background]="theme.primary"
*ngIf="currentTheme !== theme">
invert_colors
</mat-icon>
{{theme.name}}
</button>
</mat-menu>

 

9. Fix the FormFieldValidator

The FormFieldModel validationSummary is now a ErrorMessageModel : 

export declare class ErrorMessageModel {
    message: string;
    attributes: Map<string, string>;
    constructor(obj?: any);
    isActive(): boolean;
    getAttributesAsJsonObj(): {};
}

so if you have an old validator you need to change it from:

validate(field: FormFieldModel): boolean {
        if (this.isSupported(field)) {
            if (field.value && field.value.toLowerCase() === 'admin') {
                field.validationSummary = 'Sorry, the value cannot be "admin".';
                field.validationSummary.message = 'Sorry, the value cannot be "admin".';

                return false;
            }
        }
        return true;
    }

to:

    validate(field: FormFieldModel): boolean {
        if (this.isSupported(field)) {
            if (field.value && field.value.toLowerCase() === 'admin') {
                field.validationSummary.message = 'Sorry, the value cannot be "admin".';
                return false;
            }
        }
        return true;
    }
If you have generated the project with the generator you can find a validator problem in app/components/activiti/demo-field-validator.ts

10. Fix the debug-app-config.service

Open the app/services/debug-app-config.service.ts and change the code to use the Http client:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { AppConfigService, StorageService } from '@alfresco/adf-core';

@Injectable()
export class DebugAppConfigService extends AppConfigService {

    constructor(private storage: StorageService, http: HttpClient) {
        super(http);
    }

    /** @override */
    get<T>(key: string): T {
        if (key === 'ecmHost' || key === 'bpmHost') {
            return <T> (<any> this.storage.getItem(key) || super.get<T>(key));
        }
        return super.get<T>(key);
    }

}

11. Fix the validateDynamicTableRow Observable

The ValidateDynamicTableRowEvent text property is changed in message.

If you created your the project with the generator you can find a problem like that in /app/components/activiti/activiti-demo.component.ts:

formService.validateDynamicTableRow.subscribe(
    (validateDynamicTableRowEvent: ValidateDynamicTableRowEvent) => {
     const row: DynamicTableRow = validateDynamicTableRowEvent.row;
     if (row && row.value && row.value.name === 'admin') {
         validateDynamicTableRowEvent.summary.isValid = false;
         validateDynamicTableRowEvent.summary.text = 'Sorry, wrong value. You cannot use "admin".';
         validateDynamicTableRowEvent.preventDefault();
         }
    }
);

to:

formService.validateDynamicTableRow.subscribe(
  (validateDynamicTableRowEvent: ValidateDynamicTableRowEvent) => {
     const row: DynamicTableRow = validateDynamicTableRowEvent.row;
     if (row && row.value && row.value.name === 'admin') {
         validateDynamicTableRowEvent.summary.isValid = false;
         validateDynamicTableRowEvent.summary.message = 'Sorry, wrong value. You cannot use "admin".';
         validateDynamicTableRowEvent.preventDefault();
       }
   }
);

The search has been completely rewritten in the ADF 2.0.0 for have more information about the new search please refer to those links:

  1. I suggest you copy all the files from alfresco-ng2-components/demo-shell/src/app/components/search at 2.0.0 · Alfresco/alfresco-ng2-components · GitHub  in yours search folder
  2. Rename  the search-bar tag in your new /app/components/search/search-bar.component.ts:

From:

 

@Component({
    selector: 'adf-search-bar',
    templateUrl: './search-bar.component.html',
    styleUrls: ['./search-bar.component.scss']
})

to

@Component({
    selector: 'search-bar',
    templateUrl: './search-bar.component.html',
    styleUrls: ['./search-bar.component.scss']
})

 

   3. open /app/components/search/search-result.component.html and change the tag:
From
app-files-component
to
adf-files-component

13. Fix the files component 

We need to add an input parameter and some other methods to let the files.components.ts to work properly with the search component because from 2.0.0 the search doesn't have anymore a document list embedded. 

Open the app/components/files/files.component.ts:

  1. Add the those imports
    import { SimpleChanges, Output, EventEmitter } from '@angular/core';
    import { MinimalNodeEntity, NodePaging, Pagination } from 'alfresco-js-api';
    import {
        AlfrescoApiService, ContentService, TranslationService, FileUploadEvent, FolderCreatedEvent, NotificationService,
        SiteModel, UploadService, DataColumn, DataRow, UserPreferencesService
    } from '@alfresco/adf-core';
    import { DownloadZipDialogComponent} from '@alfresco/adf-content-services';

     

  2. Add the user preference service to your constructor:
     private preference: UserPreferencesService
  1. Add the following input, (note currentFolderId should be already present you need only to add the @Input decorator):

    @Input()
    currentFolderId: string = DEFAULT_FOLDER_TO_SHOW;

    @Input()
    nodeResult: NodePaging;

    @Input()
    pagination: Pagination;

    @Input()
    disableDragArea = false;

     

  2. Add the pagination events:
    @Output()
    documentListReady: EventEmitter<any> = new EventEmitter();

    @Output()
    changedPageSize: EventEmitter<Pagination> = new EventEmitter();

    @Output()
    changedPageNumber: EventEmitter<Pagination> = new EventEmitter();

    @Output()
    turnedNextPage: EventEmitter<Pagination> = new EventEmitter();

    @Output()
    turnedPreviousPage: EventEmitter<Pagination> = new EventEmitter();

    @Output()
    loadNext: EventEmitter<Pagination> = new EventEmitter();

     

  3. Add the ngOnChanges method:
    ngOnChanges(changes: SimpleChanges) {
         if (changes.nodeResult && changes.nodeResult.currentValue) {
            this.nodeResult = <NodePaging>changes.nodeResult.currentValue;
            this.pagination = this.nodeResult.list.pagination;
         }
         if (!this.pagination) {
            this.giveDefaultPaginationWhenNotDefined();
         }
    }

    giveDefaultPaginationWhenNotDefined() {
         this.pagination =  <Pagination> {
                maxItems: this.preference.paginationSize,
                skipCount: 0,
                totalItems: 0,
                hasMoreItems: false
         };
    }

     

  4. The CreateFolderDialogComponent doesn't exist anymore has been deprecated in favour of the adf-create-folder directive delete the onCreateFolderClicked method

 

Open the app/components/files/files.component.html

  1. Add the new pagination under the adf-documentlist component:
    <adf-pagination
        #standardPagination
        *ngIf="!infiniteScrolling"
        class="adf-documentlist-pagination"
        [target]="documentList"
        (changePageSize)="onChangePageSize($event)"
        (changePageNumber)="onChangePageNumber($event)"
        (nextPage)="onNextPage($event)"
        (prevPage)="onPrevPage($event)">

    </adf-pagination>
    <adf-infinite-pagination
        *ngIf="infiniteScrolling"
        [pagination]="pagination"
        [loading]="documentList.infiniteLoading"
        [pageSize]="currentMaxItems"
        (loadMore)="loadNextBatch($event)">

        {{ 'ADF-DOCUMENT-LIST.LAYOUT.LOAD_MORE' | translate }}
    </adf-infinite-pagination>

     

  2. Add the new create folder directive:

    Change from:

    <button mat-icon-button
            (click)="onCreateFolderClicked($event)">

        <mat-icon>create_new_folder</mat-icon>
    </button>

    to:

    <button
        mat-icon-button
        [adf-create-folder]="getDocumentListCurrentFolderId()">

        <mat-icon>create_new_folder</mat-icon>
    </button>

     

14. Simplify the app.module.ts

You can simplify the  app/app.modules.ts using only the 4 main modules:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { DebugAppConfigService } from './services/debug-app-config.service';
import { MaterialModule } from './material.module';
import { CustomSourcesComponent } from './components/files/custom-sources.component';
import { FormListDemoComponent } from './components/form/form-list-demo.component';
import { AppLayoutComponent } from './components/app-layout/app-layout.component';
import { AppComponent } from './app.component';
import { routing } from './app.routes';
import { ThemePickerModule } from './components/theme-picker/theme-picker';
import { SearchResultComponent } from './components/search/search-result.component';
import { SearchBarComponent } from './components/search/search-bar.component';

import { ContentModule } from '@alfresco/adf-content-services';
import { ProcessModule } from '@alfresco/adf-process-services';
import { CoreModule } from '@alfresco/adf-core';
import { InsightsModule } from '@alfresco/adf-insights';
import { AppConfigService, TRANSLATION_PROVIDER } from '@alfresco/adf-core';
import { TranslateService } from '@ngx-translate/core';
import { FlexLayoutModule } from '@angular/flex-layout';

import {
    HomeComponent,
    SettingsComponent,
    FormDemoComponent,
    ActivitiDemoComponent,
    ActivitiTaskAttachmentsComponent,
    ActivitiProcessAttachmentsComponent,
    ActivitiShowDiagramComponent,
    ActivitiAppsViewComponent,
    FormViewerComponent,
    FormNodeViewerComponent,
    FilesComponent,
    AboutComponent,
    LoginDemoComponent
} from './components/index';

let appConfigFile = 'app.config-dev.json';
if (process.env.ENV === 'production') {
    appConfigFile = 'app.config-prod.json';
}

@NgModule({
    imports: [
        BrowserModule,
        routing,
        CoreModule,
        MaterialModule,
        CoreModule,
        ContentModule,
        InsightsModule,
        ProcessModule,
        ThemePickerModule,
        FlexLayoutModule
    ],
    declarations: [
        AppLayoutComponent,
        AppComponent,
        HomeComponent,
        SearchBarComponent,
        SearchResultComponent,
        ActivitiDemoComponent,
        ActivitiTaskAttachmentsComponent,
        ActivitiProcessAttachmentsComponent,
        ActivitiAppsViewComponent,
        ActivitiShowDiagramComponent,
        FormViewerComponent,
        FormListDemoComponent,
        FormNodeViewerComponent,
        FilesComponent,
        CustomSourcesComponent,
        AboutComponent,
        LoginDemoComponent,
        SettingsComponent,
        FormDemoComponent
    ],
    providers: [
        TranslateService,
        { provide: AppConfigService, useClass: DebugAppConfigService },
        {
            provide: TRANSLATION_PROVIDER,
            multi: true,
            useValue: {
                name: 'app',
                source: 'resources'
            }
        }
    ],
    bootstrap: [AppComponent]})export class AppModule {}

15. Fix rout3er and index

Open the app/app.routes.ts:

Remove the SearchComponent  and add the following import :

import { SearchResultComponent } from './components/search/search-result.component';

change the search route:

{path: 'search', component: SearchResultComponent, canActivate: [AuthGuardEcm]},

Open the app/index.ts and remove the SearchComponent import

16. Fix the Config files

Change the webpack configuration file config/webpack.prod.js:

const webpack = require('webpack');
const webpackMerge = require('webpack-merge');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const commonConfig = require('./webpack.common.js');
const helpers = require('./helpers');
const CopyWebpackPlugin = require('copy-webpack-plugin');
var HappyPack = require('happypack');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const path = require('path');
const ENV = process.env.NODE_ENV = process.env.ENV = 'production';

const alfrescoLibs = [
    '@alfresco/adf-core',
    '@alfresco/adf-content-services',
    '@alfresco/adf-process-services',
    '@alfresco/adf-insights'
];

module.exports = webpackMerge(commonConfig, {

    devtool: 'eval',

    output: {
        path: helpers.root('dist'),
        publicPath: '/',
        filename: '[name].[hash].js',
        chunkFilename: '[id].[hash].chunk.js'
    },

    resolve: {
        extensions: ['.ts', '.js'],
        modules: [helpers.root('node_modules')]
    },

    module: {
        rules: [
            {
                test: /\.ts$/,
                include: [helpers.root('app'), helpers.root('../ng2-components')],
                use: ['happypack/loader?id=ts', 'angular2-template-loader'],
                exclude: [/node_modules/, /public/, /resources/, /dist/]
            },
            {
                test: /\.scss$/,
                use: [{
                    loader: "to-string-loader"
                }, {
                    loader: "raw-loader"
                }, {
                    loader: "sass-loader",
                    options: {
                        includePaths: [path.resolve(__dirname, helpers.root('node_modules') + '/ng2-alfresco-core/styles')]
                    }
                }]
            },
        ]
    },

    plugins: [
        new ForkTsCheckerWebpackPlugin(),

        new HappyPack({
            id: 'ts',
            threads: 4,
            loaders: [
                {
                    path: 'ts-loader',
                    query: {
                        happyPackMode: true,
                        "compilerOptions": {
                            "paths": {}
                        }
                    }
                }
            ]
        }),

        new CopyWebpackPlugin([
            ... alfrescoLibs.map(lib => {
            return {
                context: `node_modules/${lib}/bundles/assets/`,
                from: '**/*',
                to: `assets/`
            }
        })
    ]),
    new CopyWebpackPlugin([
        {
            context: `node_modules/@alfresco/adf-core/prebuilt-themes/`,
            from: '**/
*.css',
            to: 's'
        }
    ]),
    new webpack.NoEmitOnErrorsPlugin(),
    new webpack.optimize.UglifyJsPlugin({
        mangle: {
            keep_fnames: true
        },
        compress: {
            warnings: false
        },
        output: {
            comments: false
        },
        sourceMap: true
    }),
    new ExtractTextPlugin('[name].[hash].css'),
    new webpack.DefinePlugin({
        'process.env': {
            'ENV': JSON.stringify(ENV)
        }
    }),
    new CopyWebpackPlugin([
        ... alfrescoLibs.map(lib => {
        return {
            context: `../node_modules/${lib}/i18n/`,
            from: '**/*',
            to: `assets/${lib}/i18n/`
        }
    }),
    {
        from: 'app.co' +
        'nfig-prod.json',
        to: 'app.config.json'
    }
]),
new webpack.LoaderOptionsPlugin({
    htmlLoader: {
        minimize: false // workaround for ng2
    }
})]
})

Change the webpack configuration file config/webpack.common.js:

const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const helpers = require('./helpers');
const path = require('path');

module.exports = {
    entry: {
        'polyfills': './app/polyfills.ts',
        'vendor': './app/vendor.ts',
        'app': './app/main.ts'
    },

    resolveLoader: {
        alias: {
            "license-check": path.resolve(__dirname, "./loaders/license-check")
        }
    },

    module: {
        rules: [
            {
                enforce: 'pre',
                test: /\.js$/,
                include: [helpers.root('app'), helpers.root('../lib')],
                loader: 'source-map-loader',
                exclude: [/node_modules/, /public/, /resources/, /dist/]
            },
            {
                enforce: 'pre',
                test: /\.ts$/,
                loader: 'tslint-loader',
                include: [helpers.root('app')],
                options: {
                    emitErrors: true,
                    fix: true
                },
                exclude: [/node_modules/, /public/, /resources/, /dist/]
            },
            {
                enforce: 'pre',
                test: /\.ts$/,
                use: 'source-map-loader',
                exclude: [/public/, /resources/, /dist/]
            },
            {
                test: /\.html$/,
                include: [helpers.root('app'), helpers.root('../lib')],
                loader: 'html-loader',
                exclude: [/node_modules/, /public/, /resources/, /dist/]
            },
            {
                test: /\.css$/,
                exclude: [helpers.root('app'), helpers.root('../lib')],
                loader: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: 'css-loader?sourceMap'
                })
            },
            {
                test: /\.css$/,
                include: [helpers.root('app'), helpers.root('../lib')],
                loader: 'raw-loader'
            },
            {
                test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
                loader: 'file-loader?name=assets/[name].[hash].[ext]'
            }
        ]
    },

    plugins: [
        new webpack.ContextReplacementPlugin(
            // The (\\|\/) piece accounts for path separators in *nix and Windows
            /angular(\\|\/)core(\\|\/)(@angular|esm5)/,
            path.resolve(__dirname, '../src')
        ),
        new HtmlWebpackPlugin({
            template: './index.html'
        }),

        new CopyWebpackPlugin([
            {
                context: 'resources/i18n',
                from: '**/*.json',
                to: 'resources/i18n'
            },
            {
                from: 'app.config-dev.json'
            },
            {
                from: 'app.config-prod.json'
            },
            {
                from: 'favicon-96x96.png'
            },
            {
                from: 'node_modules/pdfjs-dist/build/pdf.worker.js',
                to: 'pdf.worker.js'
            },
            {
                from: 'node_modules/web-animations-js/web-animations.min.js',
                to: 'js/web-animations.min.js'
            },
            {
                from: 'node_modules/core-js/client/core.min.js',
                to: 'js/core.min.js'
            },
            {
                from: 'node_modules/custom-event-polyfill/custom-event-polyfill.js',
                to: 'js/custom-event-polyfill.js'
            },
            {
                from: 'node_modules/intl/dist/Intl.min.js',
                to: 'js/Intl.min.js'
            },
            {
                context: 'public',
                from: '',
                to: ''
            },
            {
                from: 'versions.json'
            }
        ]),

        new webpack.optimize.CommonsChunkPlugin({
            name: ['app', 'vendor', 'polyfills']
        })
    ],

    devServer: {
        contentBase: helpers.root('dist'),
        compress: true,
        port: 3000,
        historyApiFallback: true,
        host: '0.0.0.0',
        inline: true,
        proxy: {
            '/ecm': {
                target: {
                    host: "0.0.0.0",
                    protocol: 'http:',
                    port: 8080
                },
                pathRewrite: {
                    '^/ecm': ''
                },
                secure: false,
                changeOrigin: true,
                // workaround for REPO-2260
                onProxyRes: function (proxyRes, req, res) {
                    const header = proxyRes.headers['www-authenticate'];
                    if (header && header.startsWith('Basic')) {
                        proxyRes.headers['www-authenticate'] = 'x' + header;
                    }
                }
            },
            '/bpm': {
                target: {
                    host: "0.0.0.0",
                    protocol: 'http:',
                    port: 9999
                },
                pathRewrite: {
                    '^/bpm': ''
                },
                secure: false,
                changeOrigin: true,
                // workaround
                onProxyRes: function (proxyRes, req, res) {
                    const header = proxyRes.headers['www-authenticate'];
                    if (header && header.startsWith('Basic')) {
                        proxyRes.headers['www-authenticate'] = 'x' + header;
                    }
                }
            }
        }
    },

    node: {
        fs: 'empty'
    }
};

 

After all these changes, it is suggested to execute the following commands.

 

  • Clean your old distribution and dependencies.
npm run clean

 

  • Install the dependencies.
npm install

 

That's all! Now you can start again your project, as usual using npm run start.

ADF new packages table

ng2-alfresco-core -> @alfresco/adf-core
ng2-alfresco-datatable -> @alfresco/adf-core
ng2-alfresco-upload -> @alfresco/adf-core
ng2-alfresco-login ->@alfresco/adf-core
ng2-alfresco-viewer ->@alfresco/adf-core
ng2-alfresco-userinfo ->@alfresco/adf-core
ng2-activiti-form -> @alfresco/adf-core
ng2-alfresco-search -> @alfresco/adf-content-services
ng2-alfresco-social -> @alfresco/adf-content-services
ng2-alfresco-documentlist -> @alfresco/adf-content-services
ng2-alfresco-tag -> @alfresco/adf-content-services
ng2-alfresco-webscript -> @alfresco/adf-content-services
ng2-activiti-tasklist -> @alfresco/adf-process-services
ng2-activiti-processlist -> @alfresco/adf-process-services
ng2-activiti-analytics -> @alfresco/adf-insights
ng2-activiti-diagrams -> @alfresco/adf-insights

 

If everything is working fine: well done! Your project is correctly updated to the new ADF version.

If not, feel free to reply here or contact us on gitter or raising a question in the Application Development Framework space.

Attachments

    Outcomes