API Docs for: 1.0.0
Show:

File: Resources/public/js/views/services/ez-navigationhubviewservice.js

/*
 * Copyright (C) eZ Systems AS. All rights reserved.
 * For full copyright and license information view LICENSE file distributed with this source code.
 */
YUI.add('ez-navigationhubviewservice', function (Y) {
    "use strict";
    /**
     * Provides the view service component for the navigation hub
     *
     * @module ez-navigationhubviewservice
     */
    Y.namespace('eZ');

    /**
     * Navigation hub view service.
     *
     * @namespace eZ
     * @class NavigationHubViewService
     * @constructor
     * @extends eZ.ViewService
     */
    Y.eZ.NavigationHubViewService = Y.Base.create('navigationHubViewService', Y.eZ.ViewService, [Y.eZ.SideViewService], {
        initializer: function () {
            this.on('*:logOut', this._logOut);
            this.after('*:activeNavigationChange', this._navigateToFirstItemRoute);
        },

        /**
         * navigateTo event handler. it redirects the user to the given route.
         *
         * @method _navigateTo
         * @protected
         * @deprecated
         * @param {EventFacade} e
         */
        _navigateTo: function (e) {
            var route = e.route;

            console.log('[DEPRECATED] _navigateTo is deprecated');
            console.log('[DEPRECATED] this method will be removed from PlatformUI 2.0');
            this.get('app').navigateTo(route.name, route.params);
        },

        /**
         * logOut event handler, it logs out the user and redirect to the login
         * form.
         *
         * @method _logOut
         */
        _logOut: function () {
            var app = this.get('app');

            app.set('loading', true);
            app.logOut(function () {
                app.navigateTo('loginForm');
            });
        },

        /**
         * Returns true if a provided item is a NavigationItemView, false if item is a NavigationItemParameterView
         *
         * @method _isNavigationViewItem
         * @private
         * @param {Object} item
         * @return {Boolean}
         */
        _isNavigationViewItem: function (item) {
            return !!item.get;
        },

        /**
         * Redirects to the first item of the active zone
         *
         * @method _navigateToFirstItemRoute
         * @protected
         * @param {EventFacade} e
         * @param {String} e.newVal new value of `activeNavigation`
         */
        _navigateToFirstItemRoute: function (e) {
            var zone = this.get(e.newVal + 'NavigationItems'),
                firstItem,
                route;

            if (zone && zone.length > 0 && e.prevVal !== null) {
                firstItem = zone[0];

                if (this._isNavigationViewItem(firstItem)) {
                    route = firstItem.get('route');
                } else {
                    route = firstItem.config.route;
                }
                this.get('app').navigateTo(route.name, route.params);
            }
        },

        _load: function (next) {
            var api = this.get('capi'),
                loadError = false,
                service = this,
                discoveryService = api.getDiscoveryService(),
                contentService = api.getContentService(),
                user = this.get('app').get('user'),
                tasks = new Y.Parallel();

            if (user.get('avatar')) {
                contentService.loadImageVariation(user.get('avatar').variations.platformui_profileview.href, tasks.add(function (error, response) { //jshint ignore:line
                    if ( error && response.status !== 401 ) {
                        // 401 error is ignored because the user might not have the right to read
                        // his/her own avatar see https://jira.ez.no/browse/EZP-25522
                        loadError = true;
                        return;
                    }

                    service.set('userAvatar', response.document.ContentImageVariation);
                }));
            }

            discoveryService.getInfoObject('rootLocation', function (error, response){
                var rootLocationId;

                if ( error ) {
                    loadError = true;
                    return;
                }

                rootLocationId = response._href;

                service._loadLocation(rootLocationId, 'rootLocation', tasks.add(function (error) {
                    var params = {id: '', languageCode: ''};

                    if ( error ) {
                        loadError = true;
                        return;
                    }

                    params.id = service.get('rootLocation').get('id');
                    params.languageCode = service.get('rootLocation').get('contentInfo').get('mainLanguageCode');

                    service.getNavigationItem('content-structure').set(
                        'route',
                        {name: 'viewLocation', params: params}
                    );
                }));
            });

            discoveryService.getInfoObject('rootMediaFolder', function (error, response){
                var rootMediaLocationId;

                if ( error ) {
                    loadError = true;
                    return;
                }

                rootMediaLocationId = response._href;

                service._loadLocation(rootMediaLocationId, 'rootMediaLocation' , tasks.add(function (error){
                    var params = {id: '', languageCode: ''};

                    if ( error ) {
                        loadError = true;
                        return;
                    }

                    params.id = service.get('rootMediaLocation').get('id');
                    params.languageCode = service.get('rootMediaLocation').get('contentInfo').get('mainLanguageCode');

                    service.getNavigationItem('media-library').set(
                        'route',
                        {name: 'viewLocation', params: params}
                    );
                }));
            });

            tasks.done(function () {
                if ( loadError ) {
                    service._error(Y.eZ.trans('failed.to.load.root.locations', {}, 'navigationhub'));
                    return;
                }

                next(service);
            });
        },

        /**
         * Loads the given `locationId`
         *
         * @protected
         * @method _loadLocation
         * @param {Integer} locationId
         * @param {string} attributeName where data need to be loaded
         * @param {Function} callback the function to call when the location is loaded
         * @param {Boolean} callback.error the error, true if an error occurred
         * @param {ez.Location} callback.result the location object
         */
        _loadLocation: function (locationId, attributeName, callback) {
            var loadOptions = {
                    api: this.get('capi')
                },
                location = this.get(attributeName);

            location.set('id', locationId);

            location.load(loadOptions, callback);
        },

        /**
         * Returns a navigation item object. See the *NavigationItems attribute.
         *
         * @private
         * @method _getItem
         * @param {Function} constructor
         * @param {Object} config
         * @return {Object}
         */
        _getItem: function(constructor, config) {
            return {
                Constructor: constructor,
                config: config
            };
        },

        /**
         * Returns a navigation item object describing a {{#crossLink
         * "eZ.NavigationItemView"}}eZ.NavigationItemView{{/crossLink}}
         *
         * @private
         * @method _getNavigationItem
         * @param {String} title
         * @param {String} identifier
         * @param {String} routeName
         * @param {Object} routeParams
         * @return {Object}
         */
        _getNavigationItem: function (title, identifier, routeName, routeParams) {
            return this._getItem(
                Y.eZ.NavigationItemView, {
                    title: title,
                    identifier: identifier,
                    route: {
                        name: routeName,
                        params: routeParams
                    }
                }
            );
        },

        /**
         * Returns the navigation item object describing a {{#crossLink
         * "eZ.NavigationItemSubtreeView"}}eZ.NavigationItemSubtreeView{{/crossLink}}.
         *
         * @method _getSubtreeItem
         * @private
         * @param {String} title
         * @param {String} identifier
         * @param {String} locationId
         * @param {String} languageCode
         * @return {Object}
         */
        _getSubtreeItem: function (title, identifier, locationId, languageCode) {
            return new Y.eZ.NavigationItemSubtreeView( {
                title: title,
                identifier: identifier,
                route: {
                    name: 'viewLocation',
                    params: {
                        id: locationId,
                        languageCode: languageCode
                    }
                }
            });
        },

        /**
         * Returns a navigation item object describing a {{#crossLink
         * "eZ.NavigationItemParameterView"}}eZ.NavigationItemParameterView{{/crossLink}}
         *
         * @private
         * @method _getParameterItem
         * @param {String} title
         * @param {String} identifier
         * @param {String} routeName
         * @param {Object} routeParams
         * @param {String} matchParameter
         * @return {Object}
         */
        _getParameterItem: function (title, identifier, routeName, routeParams, matchParameter) {
            return this._getItem(
                Y.eZ.NavigationItemParameterView, {
                    title: title,
                    identifier: identifier,
                    route: {
                        name: routeName,
                        params: routeParams,
                    },
                    matchParameter: matchParameter
                }
            );
        },

        /**
         * Returns the parameters for the navigation hub view
         *
         * @method getViewParameters
         * @return {Object}
         */
        _getViewParameters: function () {
            return {
                user: this.get('app').get('user'),
                userAvatar: this.get('userAvatar'),
                platformNavigationItems: this.get('platformNavigationItems'),
                studioNavigationItems: this.get('studioNavigationItems'),
                studioplusNavigationItems: this.get('studioplusNavigationItems'),
                adminNavigationItems: this.get('adminNavigationItems'),
                matchedRoute: this._matchedRoute(),
            };
        },

        /**
         * A matched route object from the request. This object will be used by
         * the navigation hub view to check which navigation item view is
         * selected. A matched route object is a clone of the application active
         * route without the service, serviceInstance and callbacks entries and
         * with an additional `parameters` property holding the route
         * parameters and their values.
         *
         * @method _matchedRoute
         * @protected
         * @return {Object}
         */
        _matchedRoute: function () {
            var request = this.get('request'),
                route = request.route,
                matchedRoute = Y.merge(route);

            matchedRoute.parameters = request.params;
            delete matchedRoute.service;
            delete matchedRoute.serviceInstance;
            delete matchedRoute.callbacks;

            return matchedRoute;
        },

        /**
         * Adds a navigation item for the given zone.
         * Note: adding a navigation item will only work before the first
         * initialization of the navigation hub. As a result, in a navigation
         * hub view service plugin, this method should be called only in or from
         * the initializer method.
         *
         * @method addNavigationItem
         * @param {Object} item a navigation item, see the description of the
         * *NavigationItems attributes
         * @param {String} zone the identifier of the zone
         */
        addNavigationItem: function (item, zone) {
            this.get(zone + 'NavigationItems').push(item);
        },

        /**
         * Removes a navigation item for the given zone.
         * Note: removing a navigation item will only work before the first
         * initialization of the navigation hub. As a result, in a navigation
         * hub view service plugin, this method should be called only in or from
         * the initializer method.
         *
         * @method removeNavigationItem
         * @param {String} identifier the identifier of the navigation item to
         * remove
         * @param {String} zone the identifier of the zone
         */
        removeNavigationItem: function (identifier, zone) {
            var attr = zone + 'NavigationItems';

            this._set(attr, Y.Array.reject(this.get(attr), Y.bind(function (elt) {
                if (this._isNavigationViewItem(elt)) {
                    return elt.get('identifier') === identifier;
                } else {
                    return elt.config.identifier === identifier;
                }
            },this)));
        },

        /**
         * Retrieves a navigation item
         *
         * @method getNavigationItem
         * @param {String} identifier the identifier of the navigation item to retrieve
         * @return {Object}
         */
        getNavigationItem: function(identifier) {
            var zones = ['platform', 'studio', 'studioplus', 'admin'],
                items = [];

            Y.Array.each(zones, function (zone) {
                items = items.concat(this.get(zone + 'NavigationItems'));
            }, this);

            return Y.Array.find(items, Y.bind(function (elt) {
                if (this._isNavigationViewItem(elt)) {
                    return elt.get('identifier') === identifier;
                } else {
                    return false;
                }
            }, this));
        }
    }, {
        ATTRS: {

            /**
             * Stores the root `location`
             *
             * @attribute rootLocation
             * @type {eZ.Location}
             */
            rootLocation: {
                valueFn: function () {
                    return new Y.eZ.Location();
                },
            },

            /**
             * Stores the root media `location`
             *
             * @attribute rootMediaLocation
             * @type {eZ.Location}
             */
            rootMediaLocation: {
                valueFn: function () {
                    return new Y.eZ.Location();
                },
            },

            /**
             * Stores the navigation item objects for the 'platform' zone. Each
             * object must contain a `Constructor` property referencing
             * the constructor function to use to build the navigation item
             * view and a `config` property will be used as a configuration
             * object for the navigation item view. This configuration must
             * contain a `title` and an `identifier` properties.
             *
             * @attribute platformNavigationItems
             * @type Array
             * @default array containing the object the 'Content structure' and
             * 'Media library' items
             * @readOnly
             */
            platformNavigationItems: {
                getter: function (val) {
                    if (val) {
                        return val;
                    }

                    val = [
                        this._getSubtreeItem(
                            Y.eZ.trans("navigationhub.content.structure", {}, 'navigationhub'),
                            "content-structure",
                            this.get('rootLocation').get('id'),
                            this.get('rootLocation').get('contentInfo').get('mainLanguageCode')
                        ),
                        this._getSubtreeItem(
                            Y.eZ.trans("navigationhub.media.library",{}, 'navigationhub'),
                            "media-library",
                            this.get('rootMediaLocation').get('id'),
                            this.get('rootMediaLocation').get('contentInfo').get('mainLanguageCode')
                        ),
                    ];

                    this._set('platformNavigationItems', val);
                    return val;
                },
                readOnly: true,
            },

            /**
             * Stores the navigation item objects for the 'studioplus' zone. Each
             * object must contain a `Constructor` property referencing
             * the constructor function to use to build the navigation item
             * view and a `config` property will be used as a configuration
             * object for the navigation item view. This configuration must
             * contain a `title` and an `identifier` properties.
             *
             * @attribute studioplusNavigationItems
             * @type Array
             * @default empty array
             * @readOnly
             */
            studioplusNavigationItems: {
                getter: function (val) {
                    if (val) {
                        return val;
                    }

                    val = [
                        this._getNavigationItem(
                            "eZ Studio Plus presentation", "studioplus-presentation",
                            "studioPlusPresentation", {}
                        ),
                    ];

                    this._set('studioplusNavigationItems', val);
                    return val;
                },
                readOnly: true,
            },

            /**
             * Stores the navigation item objects for the 'studio' zone. Each
             * object must contain a `Constructor` property referencing
             * the constructor function to use to build the navigation item
             * view and a `config` property will be used as a configuration
             * object for the navigation item view. This configuration must
             * contain a `title` and an `identifier` properties.
             *
             * @attribute studioNavigationItems
             * @type Array
             * @default empty array
             * @readOnly
             */
            studioNavigationItems: {
                getter: function (val) {
                    if (val) {
                        return val;
                    }

                    val = [
                        this._getNavigationItem(
                            "eZ Studio presentation", "studio-presentation",
                            "studioPresentation", {}
                        ),
                    ];

                    this._set('studioNavigationItems', val);
                    return val;
                },
                readOnly: true,
            },

            /**
             * Stores the navigation item objects for the 'admin' zone. Each
             * object must contain a `Constructor` property referencing
             * the constructor function to use to build the navigation item
             * view and a `config` property will be used as a configuration
             * object for the navigation item view. This configuration must
             * contain a `title` and an `identifier` properties.
             *
             * @attribute adminNavigationItems
             * @type Array
             * @default array containing the items for the admin
             * @readOnly
             */
            adminNavigationItems: {
                getter: function (val) {
                    if (val) {
                        return val;
                    }

                    val = [
                        this._getParameterItem(
                            Y.eZ.trans('navigationhub.dashboard.title', {}, 'navigationhub'), "admin-dashboard",
                            "adminGenericRoute", {uri: "pjax/dashboard"}, "uri"
                        ),
                        this._getParameterItem(
                            Y.eZ.trans('navigationhub.system.information', {}, 'navigationhub'), "admin-systeminfo",
                            "adminGenericRoute", {uri: "pjax/systeminfo"}, "uri"
                        ),
                        this._getNavigationItem(
                            Y.eZ.trans('navigationhub.section.list', {}, 'navigationhub'), "admin-sections",
                            "adminSection", {uri: "pjax/section/list"}
                        ),
                        this._getNavigationItem(
                            Y.eZ.trans('navigationhub.content_type.dashboard_title', {}, 'navigationhub'), "admin-contenttypes",
                            "adminContentType", {uri: "pjax/contenttype"}
                        ),
                        this._getNavigationItem(
                            Y.eZ.trans('navigationhub.language.list', {}, 'navigationhub'), "admin-languages",
                            "adminLanguage", {uri: "pjax/language/list"}
                        ),
                        //TODO in EZP-24860. For now link to users node is defined in a static way.
                        this._getSubtreeItem(
                            Y.eZ.trans('navigationhub.user.list', {}, 'navigationhub'),
                            "admin-users",
                            "/api/ezp/v2/content/locations/1/5",
                            "eng-GB"
                        ),
                        this._getNavigationItem(
                             Y.eZ.trans('navigationhub.role.list', {}, 'navigationhub'), "admin-roles",
                            "adminRole", {uri: "pjax/role"}
                        ),
                    ];

                    this._set('adminNavigationItems', val);
                    return val;
                },
                readOnly: true,
            },

            /**
             * Stores the user's avatar image
             *
             * @attribute userAvatar
             * @type {String}
             * @default null
             */
            userAvatar: {
                value: null
            }
        },
    });
});