<commit_before>import {
    Autowired,
    AgEvent,
    Component,
    ChartMenuOptions,
    AgDialog,
    GetChartToolbarItemsParams,
    GridOptionsWrapper,
    PostConstruct,
    Promise,
    _,
    AgPanel
} from "ag-grid-community";
import { TabbedChartMenu } from "./tabbedChartMenu";
import { ChartController } from "../chartController";
import { GridChartComp } from "../gridChartComp";

type ChartToolbarButtons = {
    [key in ChartMenuOptions]: [string, () => any]
}

export class ChartMenu extends Component {

    @Autowired('gridOptionsWrapper') private gridOptionsWrapper: GridOptionsWrapper;

    public static EVENT_DOWNLOAD_CHART = 'downloadChart';

    private buttons: ChartToolbarButtons = {
        chartSettings: ['ag-icon-menu', () => this.showMenu('chartSettings')],
        chartData: ['ag-icon-data' , () => this.showMenu('chartData')],
        chartFormat: ['ag-icon-data', () => this.showMenu('chartFormat')],
        chartDownload: ['ag-icon-save', () => this.saveChart()]
    };

    private tabs: ChartMenuOptions[] = [];

    private static TEMPLATE =
        `<div class="ag-chart-menu"></div>`;

    private readonly chartController: ChartController;
    private tabbedMenu: TabbedChartMenu;
    private menuPanel: AgPanel | AgDialog | undefined;

    constructor(chartController: ChartController) {
        super(ChartMenu.TEMPLATE);
        this.chartController = chartController;
    }

    @PostConstruct
    private postConstruct(): void {
        this.createButtons();
    }

    private getToolbarOptions(): ChartMenuOptions[] {
        let tabOptions: ChartMenuOptions[] = ['chartSettings', 'chartData', 'chartFormat', 'chartDownload'];
        const toolbarItemsFunc = this.gridOptionsWrapper.getChartToolbarItemsFunc();

        if (toolbarItemsFunc) {
            const params: GetChartToolbarItemsParams = {
                api: this.gridOptionsWrapper.getApi(),
                columnApi: this.gridOptionsWrapper.getColumnApi(),
                defaultItems: tabOptions
            };

            tabOptions = (toolbarItemsFunc(params) as ChartMenuOptions[]).filter(option => {
                if (!this.buttons[option]) {
                    console.warn(`ag-Grid: '${option} is not a valid Chart Toolbar Option`);
                    return false;
                }
                return true;
            });
        }

        this.tabs = tabOptions.filter(option => option !== 'chartDownload');

        const downloadIdx = tabOptions.indexOf('chartDownload');
        const firstItem = tabOptions.find(option => option !== 'chartDownload') as ChartMenuOptions;
        const chartDownload = 'chartDownload' as ChartMenuOptions;

        if (downloadIdx !== -1) {
            if (!firstItem) {
                return [chartDownload];
            } else {
                return downloadIdx === 0 ? [chartDownload].concat([firstItem]) : [firstItem].concat([chartDownload]);
            }
        }

        return [firstItem];
    }

    private createButtons(): void {
        const chartToolbarOptions = this.getToolbarOptions();

        chartToolbarOptions.forEach(button => {
            const buttonConfig = this.buttons[button];
            const [ iconCls, callback ] = buttonConfig;
            const buttonEl = document.createElement('span');
            _.addCssClass(buttonEl, 'ag-icon');
            _.addCssClass(buttonEl, iconCls);
            this.addDestroyableEventListener(buttonEl, 'click', callback);
            this.getGui().appendChild(buttonEl);
        });
    }

    private saveChart() {
        const event: AgEvent = {
            type: ChartMenu.EVENT_DOWNLOAD_CHART
        };
        this.dispatchEvent(event);
    }

    private createMenu(defaultTab: number): Promise<AgPanel> {
        const chartComp = this.getParentComponent() as GridChartComp;
        const dockedContainer = chartComp.getDockedContainer();
        const context = this.getContext();

        const menuPanel = this.menuPanel = new AgPanel({
            minWidth: 220,
            width: 220,<commit_msg>AG-3067 - fixed bug with custom chart menu items<commit_after>import {
    Autowired,
    AgEvent,
    Component,
    ChartMenuOptions,
    AgDialog,
    GetChartToolbarItemsParams,
    GridOptionsWrapper,
    PostConstruct,
    Promise,
    _,
    AgPanel
} from "ag-grid-community";
import { TabbedChartMenu } from "./tabbedChartMenu";
import { ChartController } from "../chartController";
import { GridChartComp } from "../gridChartComp";

type ChartToolbarButtons = {
    [key in ChartMenuOptions]: [string, () => any]
}

export class ChartMenu extends Component {

    @Autowired('gridOptionsWrapper') private gridOptionsWrapper: GridOptionsWrapper;

    public static EVENT_DOWNLOAD_CHART = 'downloadChart';

    private buttons: ChartToolbarButtons = {
        chartSettings: ['ag-icon-menu', () => this.showMenu('chartSettings')],
        chartData: ['ag-icon-data' , () => this.showMenu('chartData')],
        chartFormat: ['ag-icon-data', () => this.showMenu('chartFormat')],
        chartDownload: ['ag-icon-save', () => this.saveChart()]
    };

    private tabs: ChartMenuOptions[] = [];

    private static TEMPLATE =
        `<div class="ag-chart-menu"></div>`;

    private readonly chartController: ChartController;
    private tabbedMenu: TabbedChartMenu;
    private menuPanel: AgPanel | AgDialog | undefined;

    constructor(chartController: ChartController) {
        super(ChartMenu.TEMPLATE);
        this.chartController = chartController;
    }

    @PostConstruct
    private postConstruct(): void {
        this.createButtons();
    }

    private getToolbarOptions(): ChartMenuOptions[] {
        let tabOptions: ChartMenuOptions[] = ['chartSettings', 'chartData', 'chartFormat', 'chartDownload'];
        const toolbarItemsFunc = this.gridOptionsWrapper.getChartToolbarItemsFunc();
        const ret = [] as ChartMenuOptions[];

        if (toolbarItemsFunc) {
            const params: GetChartToolbarItemsParams = {
                api: this.gridOptionsWrapper.getApi(),
                columnApi: this.gridOptionsWrapper.getColumnApi(),
                defaultItems: tabOptions
            };

            tabOptions = (toolbarItemsFunc(params) as ChartMenuOptions[]).filter(option => {
                if (!this.buttons[option]) {
                    console.warn(`ag-Grid: '${option} is not a valid Chart Toolbar Option`);
                    return false;
                }
                return true;
            });
        }

        this.tabs = tabOptions.filter(option => option !== 'chartDownload');

        const downloadIdx = tabOptions.indexOf('chartDownload');
        const firstItem = tabOptions.find(option => option !== 'chartDownload') as ChartMenuOptions;
        const chartDownload = 'chartDownload' as ChartMenuOptions;

        if (firstItem) {
            ret.push(firstItem);
        }

        if (downloadIdx !== -1) {
            return downloadIdx === 0 ? [chartDownload].concat(ret) : ret.concat([chartDownload]);
        }

        return ret;
    }

    private createButtons(): void {
        const chartToolbarOptions = this.getToolbarOptions();

        chartToolbarOptions.forEach(button => {
            const buttonConfig = this.buttons[button];
            const [ iconCls, callback ] = buttonConfig;
            const buttonEl = document.createElement('span');
            _.addCssClass(buttonEl, 'ag-icon');
            _.addCssClass(buttonEl, iconCls);
            this.addDestroyableEventListener(buttonEl, 'click', callback);
            this.getGui().appendChild(buttonEl);
        });
    }

    private saveChart() {
        const event: AgEvent = {
            type: ChartMenu.EVENT_DOWNLOAD_CHART
        };
        this.dispatchEvent(event);
    }

    private createMenu(defaultTab: number): Promise<AgPanel> {
        const chartComp = this.getParentComponent() as GridChartComp;
        const dockedContainer = chartComp.getDockedContainer();
        const context = this.getContext();

        const menuPanel = this.menuPanel = new AgPanel({
            minWidth: 220,
            width: 220,
{'fraction_non_alphanumeric': 0.11513440530256536, 'fraction_numerical': 0.002454891371056831, 'mean_word_length': 2.5973509933774834, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 27, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '377232', 'n_tokens_mistral': 2142, 'n_tokens_neox': 2095, 'n_words': 456}