Source: widget/monitor/Widget.js

(function() {
    /**
     * @namespace monitor
     * @memberof Help4.widget
     */
    Help4.widget.monitor = {};

    /**
     * @typedef {Object} Help4.widget.monitor.Widget.OnWidgetDeactivateParams
     * @property {Help4.widget.Widget} [next]
     * @property {boolean} [tour]
     * @property {boolean} [help]
     * @property {boolean} [whatsnew]
     */

    const NAME = 'monitor';

    /**
     * This widget monitors the other widgets state and initiates actions on widget changes.
     * @augments Help4.widget.Widget
     * @property {string[]} _history
     */
    Help4.widget.monitor.Widget = class extends Help4.widget.Widget {
        /** @override */
        constructor() {
            super({
                statics: {
                    _history: {init: new Help4.widget.monitor.Store()}
                }
            });
        }

        /** @override */
        getName() {
            return NAME;
        }

        /** @returns {boolean} */
        executeBack() {
            const widget = Help4.widget.getActiveInstance();
            const name = widget?.getName();
            const {_history} = this;

            switch (name) {
                case 'help':
                    if (_isLastFilter.call(this)) {
                        _history.pop();
                        _activateLast.call(this, 'filter');
                        return true;
                    }
                    break;

                case 'whatsnew':
                    if (_isLastFilter.call(this)) {  // normal WN close w/o tour start
                        _history.pop();
                        _activateLast.call(this, 'filter');
                        return true;
                    }
                    break;
            }

            return false;
        }

        /**
         * @override
         * @returns {Promise<Help4.widget.Widget.Descriptor>}
         */
        async _onGetDescriptor() {
            return {
                id: NAME,
                enabled: true,
                showPanel: false,
            };
        }

        /**
         * @override
         * @param {Help4.widget.Widget} widget
         * @param {Help4.widget.monitor.Widget.OnWidgetDeactivateParams} [data]
         * @returns {Promise<void>}
         */
        async _onWidgetDeactivate(widget, data) {
            const name = widget.getName();
            const {_history} = this;

            const handleFilterBack = () => {
                if (_isLastFilter.call(this)) {
                    _history.pop();

                    const {next} = data || {};
                    const otherWidgetStarting = next instanceof Help4.widget.Widget;

                    if (otherWidgetStarting) {
                        const {controller} = this.getContext();
                        const cmp4 = /** @type {?Help4.controller.CMP4} */ controller.getCmp4Handler();
                        const {/** @type {?Help4.control2.bubble.Panel} */ panel} = cmp4 || {};
                        panel && (panel.searchTerm = '');
                    } else {
                        _activateLast.call(this, 'filter')
                    }
                }
            }

            const {next} = data || {};
            const otherWidgetStarting = next instanceof Help4.widget.Widget;

            switch (name) {
                case 'tourlist':
                    if (data?.tour) _history.push(name);  // a tour will start
                    break;

                case 'filter':
                    if (data?.tour || data?.help) _history.push(name);  // a tour will start
                    break;

                case 'tour': {
                    const last = _history.pop() || (data?.whatsnew ? 'whatsnew' : 'tourlist');
                    _activateLast.call(this, last);
                    break;
                }

                case 'help':
                    handleFilterBack();
                    break;

                case 'whatsnew':
                    data?.tour
                        ? _history.push(name)  // a tour will start
                        : handleFilterBack();  // normal WN close w/o tour start
                    break;
            }
        }
    }

    /**
     * @memberof Help4.widget.monitor.Widget#
     * @private
     * @returns {boolean}
     */
    function _isLastFilter() {
        return this._history.top() === 'filter';
    }

    /**
     * @memberof Help4.widget.monitor.Widget#
     * @private
     * @param {string} last
     */
    function _activateLast(last) {
        const {controller} = this.getContext();
        if (controller.isOpen()) {
            const widget = Help4.widget.getInstance(last);
            widget?.activate({isReturn: true});
        }
    }
})();