/*!
 * Copyright 2018 by ChartIQ, Inc.
 * All rights reserved.
 *
 */
import React from "react";
import storeActions from "../stores/StoreActions";
import { ToggleFavoriteDropdown } from "./ToggleFavoriteDropdown";
import { useFavorites } from "../../../../../hooks/useFavorites";
import { FEAGlobals } from "../../../../../../common/Globals";
const ADVANCED_APP_LAUNCHER = "Advanced App Launcher";
const FAVORITES = "Favorites";
const FDC3 = "FDC3";
/**
 * Handles deleting a component and removing it from favorites if necessary
 * @param {*} props
 */
const DeleteApp = (props) => {
    const { isFavorited, removeFavorite } = useFavorites();
    const { name, id } = props;
    const removeFavoriteAndDelete = () => {
        if (isFavorited(name)) {
            removeFavorite(name);
        }
        storeActions.deleteApp(id);
    };
    return React.createElement("li", { onClick: removeFavoriteAndDelete }, "Delete App");
};
/**
 * This method checks an element and all of its parents to determine whether any of them
 * contain a particular class name. We use this to determine whether the user is clicking
 * inside or outside of the actions menu pop up.
 * @param {HTMLElement} element
 * @param {string} className
 */
const someParentHasClassName = (element, className) => {
    if (element.className && element.className.split(" ").indexOf(className) >= 0)
        return true;
    return element.parentNode && someParentHasClassName(element.parentNode, className);
};
/**
 * Displays a list of actions like 'View info', 'Add to favorite'
 * etc on each app in the list
 */
export default class AppActionsMenu extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            isVisible: false,
        };
        // Bind correct context
        this.onViewInfo = this.onViewInfo.bind(this);
        this.toggleMenu = this.toggleMenu.bind(this);
        this.onRemove = this.onRemove.bind(this);
        this.setMenuRef = this.setMenuRef.bind(this);
        this.deleteApp = this.deleteApp.bind(this);
        this.handleClickOutside = this.handleClickOutside.bind(this);
        this.handleWindowBlurred = this.handleWindowBlurred.bind(this);
        this.menuRef = null;
    }
    componentDidMount() {
        document.addEventListener("portal:click", this.handleClickOutside);
        // Mody on 12/12/19
        // window.blur seems to work much better than finsembleWindow's
        // blurred event. The first, is only fired when you actually click
        // away from the window, while finsembleWindow's blurred fires even
        // when you click inside the window, causing possible race conditions.
        window.addEventListener("blur", this.handleWindowBlurred);
    }
    componentWillUnmount() {
        document.removeEventListener("portal:click", this.handleClickOutside);
        window.removeEventListener("blur", this.handleWindowBlurred);
    }
    toggleMenu(e) {
        if (e) {
            e.stopPropagation();
            e.preventDefault();
        }
        this.setState({
            isVisible: !this.state.isVisible,
        });
    }
    /**
     * Opens app catalog and switches to the page when you see all
     * the details about the app
     */
    onViewInfo() {
        this.toggleMenu();
        FEAGlobals.FSBL.Clients.LauncherClient.showWindow({
            componentType: "App Catalog",
        }, {
            monitor: "mine",
            staggerPixels: 0,
            spawnIfNotFound: true,
            left: "center",
            top: "center",
        }, () => {
            // Publish this event so that catalog knows
            // what app we want to view
            // NOTE: While not ideal, without a small delay (when having to launch the app catalog) the app catalog wont receive the message as it will still be initializing
            setTimeout(() => {
                FEAGlobals.FSBL.Clients.RouterClient.transmit("viewApp", {
                    app: this.props.app,
                });
            }, 250);
        });
    }
    /**
     * Calls the storeActions.removeAppFromFolder to remove
     * an app from the currently selected folder
     */
    onRemove() {
        storeActions.removeAppFromFolder(this.props.folder.name, this.props.app);
        this.toggleMenu();
    }
    setMenuRef(node) {
        this.menuRef = node;
    }
    /**
     * This event handler is responsible for closing action menu pop ups when the user clicks outside of the pop up (what we might think of as a blur event).
     * The event is triggered by a document level click handler (via portals). When we receive the event, we determine whether the user was clicking inside
     * or outside of our action menu. If inside the menu then we do nothing (the click event will be captured and handled by react) but if the event occurred
     * outside of the action menu then we set its state to invisible.
     *
     * To determine whether we've clicked inside of the action menu we traverse the parent elements looking for a clue (a parent element that contains the class "actions-menu").
     *
     * Note: this event will fire multiple times for every click - once for each action menu on the page.
     * @param {Event} e
     */
    handleClickOutside(e) {
        var _a;
        const eventTarget = (_a = e === null || e === void 0 ? void 0 : e.detail) === null || _a === void 0 ? void 0 : _a.target;
        const clickedInMyDropdown = someParentHasClassName(eventTarget, "actions-menu");
        if (this.state.isVisible && !clickedInMyDropdown) {
            this.setState({
                isVisible: false,
            });
        }
    }
    handleWindowBlurred() {
        this.setState({
            isVisible: false,
        });
    }
    /**
     * Calls storeActions.deleteApp() to delete an app
     * from all folders and from apps list
     */
    deleteApp() {
        storeActions.deleteApp(this.props.app.appID);
    }
    renderList() {
        var _a;
        // The 'View info' action is only visible on apps
        // that have the source property and with a value of FDC3
        const apps = storeActions.getAllApps();
        const app = apps[this.props.app.appID];
        const { folder } = this.props;
        return (React.createElement("div", { className: "actions-menu", style: { right: 0 } },
            React.createElement("ul", null,
                React.createElement("li", null,
                    React.createElement(ToggleFavoriteDropdown, { id: app.name, category: "Application", name: (_a = app.displayName) !== null && _a !== void 0 ? _a : app.name, icon: app.icon, instance: this })),
                app.source && app.source === FDC3 && React.createElement("li", { onClick: this.onViewInfo }, "View Info"),
                !app.source && app.canDelete && React.createElement(DeleteApp, { name: app.name, id: this.props.app.appID }),
                [ADVANCED_APP_LAUNCHER, FAVORITES].indexOf(folder.name) === -1 && (React.createElement("li", { onClick: this.onRemove },
                    "Remove from ",
                    folder.name)))));
    }
    render() {
        return (React.createElement("div", { ref: this.setMenuRef, className: "actions-menu-wrapper", onClick: this.toggleMenu },
            React.createElement("span", null,
                React.createElement("i", { className: "ff-dots-vert", id: this.props.app.appID })),
            this.state.isVisible && this.renderList()));
    }
}
//# sourceMappingURL=AppActionsMenu.js.map