@ag-grid-enterprise/menu
Version:
Advanced Data Grid / Data Table supporting Javascript / Typescript / React / Angular / Vue
1,403 lines (1,395 loc) • 69.7 kB
JavaScript
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// enterprise-modules/menu/src/main.ts
var main_exports = {};
__export(main_exports, {
MenuModule: () => MenuModule
});
module.exports = __toCommonJS(main_exports);
// enterprise-modules/menu/src/menuModule.ts
var import_core12 = require("@ag-grid-community/core");
var import_core13 = require("@ag-grid-enterprise/core");
// enterprise-modules/menu/src/menu/chartMenuItemMapper.ts
var import_core = require("@ag-grid-community/core");
var ChartMenuItemMapper = class _ChartMenuItemMapper extends import_core.BeanStub {
constructor() {
super(...arguments);
this.beanName = "chartMenuItemMapper";
}
wireBeans(beans) {
this.chartService = beans.chartService;
}
getChartItems(key) {
if (!this.chartService) {
this.gos.assertModuleRegistered(import_core.ModuleNames.GridChartsModule, `the Context Menu key "${key}"`);
return void 0;
}
const builder = key === "pivotChart" ? new PivotMenuItemMapper(this.gos, this.chartService, this.localeService) : new RangeMenuItemMapper(this.gos, this.chartService, this.localeService);
const isEnterprise = this.chartService.isEnterprise();
let topLevelMenuItem = builder.getMenuItem();
if (topLevelMenuItem && topLevelMenuItem.subMenu && !isEnterprise) {
const filterEnterpriseItems = (m) => ({
...m,
subMenu: m.subMenu?.filter((menu) => !menu._enterprise).map((menu) => filterEnterpriseItems(menu))
});
topLevelMenuItem = filterEnterpriseItems(topLevelMenuItem);
}
const chartGroupsDef = this.gos.get("chartToolPanelsDef")?.settingsPanel?.chartGroupsDef;
if (chartGroupsDef) {
topLevelMenuItem = _ChartMenuItemMapper.filterAndOrderChartMenu(
topLevelMenuItem,
chartGroupsDef,
builder.getConfigLookup()
);
}
return this.cleanInternals(topLevelMenuItem);
}
// Remove our internal _key and _enterprise properties so this does not leak out of the class on the menu items.
cleanInternals(menuItem) {
if (!menuItem) {
return menuItem;
}
const removeKeys = (m) => {
delete m?._key;
delete m?._enterprise;
m?.subMenu?.forEach((s) => removeKeys(s));
return m;
};
return removeKeys(menuItem);
}
static buildLookup(menuItem) {
const itemLookup = {};
const addItem = (item) => {
itemLookup[item._key] = item;
if (item.subMenu) {
item.subMenu.forEach((s) => addItem(s));
}
};
addItem(menuItem);
return itemLookup;
}
/**
* Make the MenuItem match the charts provided and their ordering on the ChartGroupsDef config object as provided by the user.
*/
static filterAndOrderChartMenu(topLevelMenuItem, chartGroupsDef, configLookup) {
const menuItemLookup = this.buildLookup(topLevelMenuItem);
const orderedAndFiltered = { ...topLevelMenuItem, subMenu: [] };
Object.entries(chartGroupsDef).forEach(([group, chartTypes]) => {
const chartConfigGroup = configLookup[group];
if (chartConfigGroup === null)
return;
if (chartConfigGroup == void 0) {
(0, import_core._warnOnce)(`invalid chartGroupsDef config '${group}'`);
return void 0;
}
const menuItem = menuItemLookup[chartConfigGroup._key];
if (menuItem) {
if (menuItem.subMenu) {
const subMenus = chartTypes.map((chartType) => {
const itemKey = chartConfigGroup[chartType];
if (itemKey == void 0) {
(0, import_core._warnOnce)(`invalid chartGroupsDef config '${group}.${chartType}'`);
return void 0;
}
return menuItemLookup[itemKey];
}).filter((s) => s !== void 0);
if (subMenus.length > 0) {
menuItem.subMenu = subMenus;
orderedAndFiltered.subMenu?.push(menuItem);
}
} else {
orderedAndFiltered.subMenu?.push(menuItem);
}
}
});
if (orderedAndFiltered.subMenu?.length == 0) {
return void 0;
}
return orderedAndFiltered;
}
};
var PivotMenuItemMapper = class {
constructor(gos, chartService, localeService) {
this.gos = gos;
this.chartService = chartService;
this.localeService = localeService;
}
getMenuItem() {
const localeTextFunc = this.localeService.getLocaleTextFunc();
const getMenuItem = (localeKey, defaultText, chartType, key, enterprise = false) => {
return {
name: localeTextFunc(localeKey, defaultText),
action: () => this.chartService.createPivotChart({ chartType }),
_key: key,
_enterprise: enterprise
};
};
return {
name: localeTextFunc("pivotChart", "Pivot Chart"),
_key: "pivotChart",
subMenu: [
{
_key: "pivotColumnChart",
name: localeTextFunc("columnChart", "Column"),
subMenu: [
getMenuItem("groupedColumn", "Grouped‎", "groupedColumn", "pivotGroupedColumn"),
getMenuItem("stackedColumn", "Stacked‎", "stackedColumn", "pivotStackedColumn"),
getMenuItem(
"normalizedColumn",
"100% Stacked‎",
"normalizedColumn",
"pivotNormalizedColumn"
)
]
},
{
_key: "pivotBarChart",
name: localeTextFunc("barChart", "Bar"),
subMenu: [
getMenuItem("groupedBar", "Grouped‎", "groupedBar", "pivotGroupedBar"),
getMenuItem("stackedBar", "Stacked‎", "stackedBar", "pivotStackedBar"),
getMenuItem("normalizedBar", "100% Stacked‎", "normalizedBar", "pivotNormalizedBar")
]
},
{
_key: "pivotPieChart",
name: localeTextFunc("pieChart", "Pie"),
subMenu: [
getMenuItem("pie", "Pie‎", "pie", "pivotPie"),
getMenuItem("donut", "Donut‎", "donut", "pivotDonut")
]
},
getMenuItem("line", "Line‎", "line", "pivotLineChart"),
{
_key: "pivotXYChart",
name: localeTextFunc("xyChart", "X Y (Scatter)"),
subMenu: [
getMenuItem("scatter", "Scatter‎", "scatter", "pivotScatter"),
getMenuItem("bubble", "Bubble‎", "bubble", "pivotBubble")
]
},
{
_key: "pivotAreaChart",
name: localeTextFunc("areaChart", "Area"),
subMenu: [
getMenuItem("area", "Area‎", "area", "pivotArea"),
getMenuItem("stackedArea", "Stacked‎", "stackedArea", "pivotStackedArea"),
getMenuItem("normalizedArea", "100% Stacked‎", "normalizedArea", "pivotNormalizedArea")
]
},
{
_key: "pivotStatisticalChart",
_enterprise: false,
// histogram chart is available in both community and enterprise distributions
name: localeTextFunc("statisticalChart", "Statistical"),
subMenu: [getMenuItem("histogramChart", "Histogram‎", "histogram", "pivotHistogram", false)]
},
{
_key: "pivotHierarchicalChart",
_enterprise: true,
name: localeTextFunc("hierarchicalChart", "Hierarchical"),
subMenu: [
getMenuItem("treemapChart", "Treemap‎", "treemap", "pivotTreemap", true),
getMenuItem("sunburstChart", "Sunburst‎", "sunburst", "pivotSunburst", true)
]
},
{
_key: "pivotCombinationChart",
name: localeTextFunc("combinationChart", "Combination"),
subMenu: [
getMenuItem("columnLineCombo", "Column & Line‎", "columnLineCombo", "pivotColumnLineCombo"),
getMenuItem("AreaColumnCombo", "Area & Column‎", "areaColumnCombo", "pivotAreaColumnCombo")
]
}
],
icon: (0, import_core._createIconNoSpan)("chart", this.gos, void 0)
};
}
getConfigLookup() {
return {
columnGroup: {
_key: "pivotColumnChart",
column: "pivotGroupedColumn",
stackedColumn: "pivotStackedColumn",
normalizedColumn: "pivotNormalizedColumn"
},
barGroup: {
_key: "pivotBarChart",
bar: "pivotGroupedBar",
stackedBar: "pivotStackedBar",
normalizedBar: "pivotNormalizedBar"
},
pieGroup: {
_key: "pivotPieChart",
pie: "pivotPie",
donut: "pivotDonut",
doughnut: "pivotDonut"
},
lineGroup: {
_key: "pivotLineChart",
line: "pivotLineChart"
},
scatterGroup: {
_key: "pivotXYChart",
bubble: "pivotBubble",
scatter: "pivotScatter"
},
areaGroup: {
_key: "pivotAreaChart",
area: "pivotArea",
stackedArea: "pivotStackedArea",
normalizedArea: "pivotNormalizedArea"
},
combinationGroup: {
_key: "pivotCombinationChart",
columnLineCombo: "pivotColumnLineCombo",
areaColumnCombo: "pivotAreaColumnCombo",
customCombo: null
// Not currently supported
},
hierarchicalGroup: {
_key: "pivotHierarchicalChart",
treemap: "pivotTreemap",
sunburst: "pivotSunburst"
},
statisticalGroup: {
_key: "pivotStatisticalChart",
histogram: "pivotHistogram",
// Some statistical charts do not currently support pivot mode
rangeBar: null,
rangeArea: null,
boxPlot: null
},
// Polar charts do not support pivot mode
polarGroup: null,
// Specialized charts do not currently support pivot mode
specializedGroup: null
};
}
};
var RangeMenuItemMapper = class {
constructor(gos, chartService, localeService) {
this.gos = gos;
this.chartService = chartService;
this.localeService = localeService;
}
getMenuItem() {
const localeTextFunc = this.localeService.getLocaleTextFunc();
const getMenuItem = (localeKey, defaultText, chartType, key, enterprise = false) => {
return {
name: localeTextFunc(localeKey, defaultText),
action: () => this.chartService.createChartFromCurrentRange(chartType),
_key: key,
_enterprise: enterprise
};
};
return {
name: localeTextFunc("chartRange", "Chart Range"),
_key: "chartRange",
subMenu: [
{
name: localeTextFunc("columnChart", "Column"),
subMenu: [
getMenuItem("groupedColumn", "Grouped‎", "groupedColumn", "rangeGroupedColumn"),
getMenuItem("stackedColumn", "Stacked‎", "stackedColumn", "rangeStackedColumn"),
getMenuItem(
"normalizedColumn",
"100% Stacked‎",
"normalizedColumn",
"rangeNormalizedColumn"
)
],
_key: "rangeColumnChart"
},
{
name: localeTextFunc("barChart", "Bar"),
subMenu: [
getMenuItem("groupedBar", "Grouped‎", "groupedBar", "rangeGroupedBar"),
getMenuItem("stackedBar", "Stacked‎", "stackedBar", "rangeStackedBar"),
getMenuItem("normalizedBar", "100% Stacked‎", "normalizedBar", "rangeNormalizedBar")
],
_key: "rangeBarChart"
},
{
name: localeTextFunc("pieChart", "Pie"),
subMenu: [
getMenuItem("pie", "Pie‎", "pie", "rangePie"),
getMenuItem("donut", "Donut‎", "donut", "rangeDonut")
],
_key: "rangePieChart"
},
getMenuItem("line", "Line‎", "line", "rangeLineChart"),
{
name: localeTextFunc("xyChart", "X Y (Scatter)"),
subMenu: [
getMenuItem("scatter", "Scatter‎", "scatter", "rangeScatter"),
getMenuItem("bubble", "Bubble‎", "bubble", "rangeBubble")
],
_key: "rangeXYChart"
},
{
name: localeTextFunc("areaChart", "Area"),
subMenu: [
getMenuItem("area", "Area‎", "area", "rangeArea"),
getMenuItem("stackedArea", "Stacked‎", "stackedArea", "rangeStackedArea"),
getMenuItem("normalizedArea", "100% Stacked‎", "normalizedArea", "rangeNormalizedArea")
],
_key: "rangeAreaChart"
},
{
name: localeTextFunc("polarChart", "Polar"),
subMenu: [
getMenuItem("radarLine", "Radar Line‎", "radarLine", "rangeRadarLine"),
getMenuItem("radarArea", "Radar Area‎", "radarArea", "rangeRadarArea"),
getMenuItem("nightingale", "Nightingale‎", "nightingale", "rangeNightingale"),
getMenuItem("radialColumn", "Radial Column‎", "radialColumn", "rangeRadialColumn"),
getMenuItem("radialBar", "Radial Bar‎", "radialBar", "rangeRadialBar")
],
_key: "rangePolarChart",
_enterprise: true
},
{
name: localeTextFunc("statisticalChart", "Statistical"),
subMenu: [
getMenuItem("boxPlot", "Box Plot‎", "boxPlot", "rangeBoxPlot", true),
getMenuItem("histogramChart", "Histogram‎", "histogram", "rangeHistogram", false),
getMenuItem("rangeBar", "Range Bar‎", "rangeBar", "rangeRangeBar", true),
getMenuItem("rangeArea", "Range Area‎", "rangeArea", "rangeRangeArea", true)
],
_key: "rangeStatisticalChart",
_enterprise: false
// histogram chart is available in both community and enterprise distributions
},
{
name: localeTextFunc("hierarchicalChart", "Hierarchical"),
subMenu: [
getMenuItem("treemap", "Treemap‎", "treemap", "rangeTreemap"),
getMenuItem("sunburst", "Sunburst‎", "sunburst", "rangeSunburst")
],
_key: "rangeHierarchicalChart",
_enterprise: true
},
{
name: localeTextFunc("specializedChart", "Specialized"),
subMenu: [
getMenuItem("heatmap", "Heatmap‎", "heatmap", "rangeHeatmap"),
getMenuItem("waterfall", "Waterfall‎", "waterfall", "rangeWaterfall")
],
_key: "rangeSpecializedChart",
_enterprise: true
},
{
name: localeTextFunc("combinationChart", "Combination"),
subMenu: [
getMenuItem("columnLineCombo", "Column & Line‎", "columnLineCombo", "rangeColumnLineCombo"),
getMenuItem("AreaColumnCombo", "Area & Column‎", "areaColumnCombo", "rangeAreaColumnCombo")
],
_key: "rangeCombinationChart"
}
],
icon: (0, import_core._createIconNoSpan)("chart", this.gos, void 0)
};
}
getConfigLookup() {
return {
columnGroup: {
_key: "rangeColumnChart",
column: "rangeGroupedColumn",
stackedColumn: "rangeStackedColumn",
normalizedColumn: "rangeNormalizedColumn"
},
barGroup: {
_key: "rangeBarChart",
bar: "rangeGroupedBar",
stackedBar: "rangeStackedBar",
normalizedBar: "rangeNormalizedBar"
},
pieGroup: {
_key: "rangePieChart",
pie: "rangePie",
donut: "rangeDonut",
doughnut: "rangeDonut"
},
lineGroup: {
_key: "rangeLineChart",
line: "rangeLineChart"
},
scatterGroup: {
_key: "rangeXYChart",
bubble: "rangeBubble",
scatter: "rangeScatter"
},
areaGroup: {
_key: "rangeAreaChart",
area: "rangeArea",
stackedArea: "rangeStackedArea",
normalizedArea: "rangeNormalizedArea"
},
polarGroup: {
_key: "rangePolarChart",
radarLine: "rangeRadarLine",
radarArea: "rangeRadarArea",
nightingale: "rangeNightingale",
radialColumn: "rangeRadialColumn",
radialBar: "rangeRadialBar"
},
statisticalGroup: {
_key: "rangeStatisticalChart",
boxPlot: "rangeBoxPlot",
histogram: "rangeHistogram",
rangeBar: "rangeRangeBar",
rangeArea: "rangeRangeArea"
},
hierarchicalGroup: {
_key: "rangeHierarchicalChart",
treemap: "rangeTreemap",
sunburst: "rangeSunburst"
},
specializedGroup: {
_key: "rangeSpecializedChart",
heatmap: "rangeHeatmap",
waterfall: "rangeWaterfall"
},
combinationGroup: {
_key: "rangeCombinationChart",
columnLineCombo: "rangeColumnLineCombo",
areaColumnCombo: "rangeAreaColumnCombo",
customCombo: null
// Not currently supported
}
};
}
};
// enterprise-modules/menu/src/menu/columnChooserFactory.ts
var import_core2 = require("@ag-grid-community/core");
var import_column_tool_panel = require("@ag-grid-enterprise/column-tool-panel");
var import_core3 = require("@ag-grid-enterprise/core");
var ColumnChooserFactory = class extends import_core2.BeanStub {
constructor() {
super(...arguments);
this.beanName = "columnChooserFactory";
}
wireBeans(beans) {
this.focusService = beans.focusService;
this.menuUtils = beans.menuUtils;
this.visibleColsService = beans.visibleColsService;
}
createColumnSelectPanel(parent, column, draggable, params) {
const columnSelectPanel = parent.createManagedBean(new import_column_tool_panel.AgPrimaryCols());
const columnChooserParams = params ?? column?.getColDef().columnChooserParams ?? column?.getColDef().columnsMenuParams ?? {};
const {
contractColumnSelection,
suppressColumnExpandAll,
suppressColumnFilter,
suppressColumnSelectAll,
suppressSyncLayoutWithGrid,
columnLayout
} = columnChooserParams;
columnSelectPanel.init(
!!draggable,
this.gos.addGridCommonParams({
suppressColumnMove: false,
suppressValues: false,
suppressPivots: false,
suppressRowGroups: false,
suppressPivotMode: false,
contractColumnSelection: !!contractColumnSelection,
suppressColumnExpandAll: !!suppressColumnExpandAll,
suppressColumnFilter: !!suppressColumnFilter,
suppressColumnSelectAll: !!suppressColumnSelectAll,
suppressSyncLayoutWithGrid: !!columnLayout || !!suppressSyncLayoutWithGrid,
onStateUpdated: () => {
}
}),
"columnMenu"
);
if (columnLayout) {
columnSelectPanel.setColumnLayout(columnLayout);
}
return columnSelectPanel;
}
showColumnChooser({ column, chooserParams, eventSource }) {
this.hideActiveColumnChooser();
const columnSelectPanel = this.createColumnSelectPanel(this, column, true, chooserParams);
const translate = this.localeService.getLocaleTextFunc();
const columnIndex = this.visibleColsService.getAllCols().indexOf(column);
const headerPosition = column ? this.focusService.getFocusedHeader() : null;
this.activeColumnChooserDialog = this.createBean(
new import_core3.AgDialog({
title: translate("chooseColumns", "Choose Columns"),
component: columnSelectPanel,
width: 300,
height: 300,
resizable: true,
movable: true,
centered: true,
closable: true,
afterGuiAttached: () => {
this.focusService.findNextFocusableElement(columnSelectPanel.getGui())?.focus({
preventScroll: true
});
this.dispatchVisibleChangedEvent(true, column);
},
closedCallback: (event) => {
const eComp = this.activeColumnChooser.getGui();
this.destroyBean(this.activeColumnChooser);
this.activeColumnChooser = void 0;
this.activeColumnChooserDialog = void 0;
this.dispatchVisibleChangedEvent(false, column);
if (column) {
this.menuUtils.restoreFocusOnClose(
{ column, headerPosition, columnIndex, eventSource },
eComp,
event,
true
);
}
},
postProcessPopupParams: {
type: "columnChooser",
column,
eventSource
}
})
);
this.activeColumnChooser = columnSelectPanel;
}
hideActiveColumnChooser() {
if (this.activeColumnChooserDialog) {
this.destroyBean(this.activeColumnChooserDialog);
}
}
dispatchVisibleChangedEvent(visible, column) {
this.eventService.dispatchEvent({
type: "columnMenuVisibleChanged",
visible,
switchingTab: false,
key: "columnChooser",
column: column ?? null
});
}
};
// enterprise-modules/menu/src/menu/columnMenuFactory.ts
var import_core4 = require("@ag-grid-community/core");
var import_core5 = require("@ag-grid-enterprise/core");
var MENU_ITEM_SEPARATOR = "separator";
var ColumnMenuFactory = class extends import_core4.BeanStub {
constructor() {
super(...arguments);
this.beanName = "columnMenuFactory";
}
wireBeans(beans) {
this.menuItemMapper = beans.menuItemMapper;
this.columnModel = beans.columnModel;
this.funcColsService = beans.funcColsService;
this.menuService = beans.menuService;
}
createMenu(parent, menuItems, column, sourceElement) {
const menuList = parent.createManagedBean(
new import_core5.AgMenuList(0, {
column: column ?? null,
node: null,
value: null
})
);
const menuItemsMapped = this.menuItemMapper.mapWithStockItems(
menuItems,
column ?? null,
sourceElement,
"columnMenu"
);
menuList.addMenuItems(menuItemsMapped);
return menuList;
}
// columnGroup to be added
// eslint-disable-next-line @typescript-eslint/no-unused-vars
getMenuItems(column, columnGroup) {
const defaultItems = this.getDefaultMenuOptions(column);
let result;
const columnMainMenuItems = column?.getColDef().mainMenuItems;
if (Array.isArray(columnMainMenuItems)) {
result = columnMainMenuItems;
} else if (typeof columnMainMenuItems === "function") {
result = columnMainMenuItems(
this.gos.addGridCommonParams({
column,
defaultItems
})
);
} else {
const userFunc = this.gos.getCallback("getMainMenuItems");
if (userFunc && column) {
result = userFunc({
column,
defaultItems
});
} else {
result = defaultItems;
}
}
(0, import_core4._removeRepeatsFromArray)(result, MENU_ITEM_SEPARATOR);
return result;
}
getDefaultMenuOptions(column) {
const result = [];
const isLegacyMenuEnabled = this.menuService.isLegacyMenuEnabled();
if (!column) {
if (!isLegacyMenuEnabled) {
result.push("columnChooser");
}
result.push("resetColumns");
return result;
}
const allowPinning = !column.getColDef().lockPinned;
const rowGroupCount = this.funcColsService.getRowGroupColumns().length;
const doingGrouping = rowGroupCount > 0;
const allowValue = column.isAllowValue();
const allowRowGroup = column.isAllowRowGroup();
const isPrimary = column.isPrimary();
const pivotModeOn = this.columnModel.isPivotMode();
const isInMemoryRowModel = (0, import_core4._isClientSideRowModel)(this.gos);
const usingTreeData = this.gos.get("treeData");
const allowValueAgg = (
// if primary, then only allow aggValue if grouping and it's a value columns
isPrimary && doingGrouping && allowValue || // secondary columns can always have aggValue, as it means it's a pivot value column
!isPrimary
);
if (!isLegacyMenuEnabled && column.isSortable()) {
const sort = column.getSort();
if (sort !== "asc") {
result.push("sortAscending");
}
if (sort !== "desc") {
result.push("sortDescending");
}
if (sort) {
result.push("sortUnSort");
}
result.push(MENU_ITEM_SEPARATOR);
}
if (this.menuService.isFilterMenuItemEnabled(column)) {
result.push("columnFilter");
result.push(MENU_ITEM_SEPARATOR);
}
if (allowPinning) {
result.push("pinSubMenu");
}
if (allowValueAgg) {
result.push("valueAggSubMenu");
}
if (allowPinning || allowValueAgg) {
result.push(MENU_ITEM_SEPARATOR);
}
result.push("autoSizeThis");
result.push("autoSizeAll");
result.push(MENU_ITEM_SEPARATOR);
const showRowGroup = column.getColDef().showRowGroup;
if (showRowGroup) {
result.push("rowUnGroup");
} else if (allowRowGroup && column.isPrimary()) {
if (column.isRowGroupActive()) {
const groupLocked = this.columnModel.isColGroupLocked(column);
if (!groupLocked) {
result.push("rowUnGroup");
}
} else {
result.push("rowGroup");
}
}
result.push(MENU_ITEM_SEPARATOR);
if (!isLegacyMenuEnabled) {
result.push("columnChooser");
}
result.push("resetColumns");
const allowExpandAndContract = isInMemoryRowModel && (usingTreeData || rowGroupCount > (pivotModeOn ? 1 : 0));
if (allowExpandAndContract) {
result.push("expandAll");
result.push("contractAll");
}
return result;
}
};
// enterprise-modules/menu/src/menu/contextMenu.ts
var import_core6 = require("@ag-grid-community/core");
var import_core7 = require("@ag-grid-enterprise/core");
var CSS_MENU = "ag-menu";
var CSS_CONTEXT_MENU_OPEN = "ag-context-menu-open";
var ContextMenuFactory = class extends import_core6.BeanStub {
constructor() {
super(...arguments);
this.beanName = "contextMenuFactory";
}
wireBeans(beans) {
this.popupService = beans.popupService;
this.ctrlsService = beans.ctrlsService;
this.columnModel = beans.columnModel;
this.menuUtils = beans.menuUtils;
this.rangeService = beans.rangeService;
this.focusService = beans.focusService;
}
hideActiveMenu() {
this.destroyBean(this.activeMenu);
}
getMenuItems(node, column, value) {
const defaultMenuOptions = [];
if ((0, import_core6._exists)(node) && this.gos.isModuleRegistered(import_core6.ModuleNames.ClipboardModule)) {
if (column) {
if (!this.gos.get("suppressCutToClipboard")) {
defaultMenuOptions.push("cut");
}
defaultMenuOptions.push("copy", "copyWithHeaders", "copyWithGroupHeaders", "paste", "separator");
}
}
if (this.gos.get("enableCharts") && this.gos.isModuleRegistered(import_core6.ModuleNames.GridChartsModule)) {
if (this.columnModel.isPivotMode()) {
defaultMenuOptions.push("pivotChart");
}
if (this.rangeService && !this.rangeService.isEmpty()) {
defaultMenuOptions.push("chartRange");
}
}
if ((0, import_core6._exists)(node)) {
const csvModuleMissing = !this.gos.isModuleRegistered(import_core6.ModuleNames.CsvExportModule);
const excelModuleMissing = !this.gos.isModuleRegistered(import_core6.ModuleNames.ExcelExportModule);
const suppressExcel = this.gos.get("suppressExcelExport") || excelModuleMissing;
const suppressCsv = this.gos.get("suppressCsvExport") || csvModuleMissing;
const onIPad = (0, import_core6._isIOSUserAgent)();
const anyExport = !onIPad && (!suppressExcel || !suppressCsv);
if (anyExport) {
defaultMenuOptions.push("export");
}
}
const defaultItems = defaultMenuOptions.length ? defaultMenuOptions : void 0;
const columnContextMenuItems = column?.getColDef().contextMenuItems;
if (Array.isArray(columnContextMenuItems)) {
return columnContextMenuItems;
}
if (typeof columnContextMenuItems === "function") {
return columnContextMenuItems(
this.gos.addGridCommonParams({
column,
node,
value,
defaultItems
})
);
}
const userFunc = this.gos.getCallback("getContextMenuItems");
if (userFunc) {
return userFunc({ column, node, value, defaultItems });
}
return defaultMenuOptions;
}
onContextMenu(mouseEvent, touchEvent, rowNode, column, value, anchorToElement) {
this.menuUtils.onContextMenu(
mouseEvent,
touchEvent,
(eventOrTouch) => this.showMenu(rowNode, column, value, eventOrTouch, anchorToElement)
);
}
showMenu(node, column, value, mouseEvent, anchorToElement) {
const menuItems = this.getMenuItems(node, column, value);
const eGridBodyGui = this.ctrlsService.getGridBodyCtrl().getGui();
if (menuItems === void 0 || (0, import_core6._missingOrEmpty)(menuItems)) {
return false;
}
const menu = new ContextMenu(menuItems, column, node, value);
this.createBean(menu);
const eMenuGui = menu.getGui();
if (!column) {
this.focusService.clearFocusedCell();
}
const positionParams = {
column,
rowNode: node,
type: "contextMenu",
mouseEvent,
ePopup: eMenuGui,
// move one pixel away so that accidentally double clicking
// won't show the browser's contextmenu
nudgeY: 1
};
const translate = this.localeService.getLocaleTextFunc();
const addPopupRes = this.popupService.addPopup({
modal: true,
eChild: eMenuGui,
closeOnEsc: true,
closedCallback: (e) => {
eGridBodyGui.classList.remove(CSS_CONTEXT_MENU_OPEN);
this.destroyBean(menu);
this.dispatchVisibleChangedEvent(false, e === void 0 ? "api" : "ui");
},
click: mouseEvent,
positionCallback: () => {
const isRtl = this.gos.get("enableRtl");
this.popupService.positionPopupUnderMouseEvent({
...positionParams,
nudgeX: isRtl ? (eMenuGui.offsetWidth + 1) * -1 : 1
});
},
// so when browser is scrolled down, or grid is scrolled, context menu stays with cell
anchorToElement,
ariaLabel: translate("ariaLabelContextMenu", "Context Menu")
});
if (addPopupRes) {
eGridBodyGui.classList.add(CSS_CONTEXT_MENU_OPEN);
menu.afterGuiAttached({ container: "contextMenu", hidePopup: addPopupRes.hideFunc });
}
if (this.activeMenu) {
this.hideActiveMenu();
}
this.activeMenu = menu;
menu.addEventListener("destroyed", () => {
if (this.activeMenu === menu) {
this.activeMenu = null;
}
});
if (addPopupRes) {
menu.addEventListener(
"closeMenu",
(e) => addPopupRes.hideFunc({
mouseEvent: e.mouseEvent ?? void 0,
keyboardEvent: e.keyboardEvent ?? void 0,
forceHide: true
})
);
}
const isApi = mouseEvent && mouseEvent instanceof MouseEvent && mouseEvent.type === "mousedown";
this.dispatchVisibleChangedEvent(true, isApi ? "api" : "ui");
return true;
}
dispatchVisibleChangedEvent(visible, source = "ui") {
this.eventService.dispatchEvent({
type: "contextMenuVisibleChanged",
visible,
source
});
}
};
var ContextMenu = class extends import_core6.Component {
constructor(menuItems, column, node, value) {
super(
/* html */
`<div class="${CSS_MENU}" role="presentation"></div>`
);
this.menuItems = menuItems;
this.column = column;
this.node = node;
this.value = value;
this.menuList = null;
this.focusedCell = null;
}
wireBeans(beans) {
this.focusService = beans.focusService;
this.menuItemMapper = beans.menuItemMapper;
this.cellPositionUtils = beans.cellPositionUtils;
}
postConstruct() {
const menuList = this.createManagedBean(
new import_core7.AgMenuList(0, {
column: this.column,
node: this.node,
value: this.value
})
);
const menuItemsMapped = this.menuItemMapper.mapWithStockItems(
this.menuItems,
null,
() => this.getGui(),
"contextMenu"
);
menuList.addMenuItems(menuItemsMapped);
this.appendChild(menuList);
this.menuList = menuList;
menuList.addEventListener("closeMenu", (e) => this.dispatchLocalEvent(e));
}
afterGuiAttached(params) {
if (params.hidePopup) {
this.addDestroyFunc(params.hidePopup);
}
this.focusedCell = this.focusService.getFocusedCell();
if (this.menuList) {
this.focusService.focusInto(this.menuList.getGui());
}
}
restoreFocusedCell() {
const currentFocusedCell = this.focusService.getFocusedCell();
if (currentFocusedCell && this.focusedCell && this.cellPositionUtils.equals(currentFocusedCell, this.focusedCell)) {
const { rowIndex, rowPinned, column } = this.focusedCell;
if ((0, import_core6._isNothingFocused)(this.gos)) {
this.focusService.setFocusedCell({
rowIndex,
column,
rowPinned,
forceBrowserFocus: true,
preventScrollOnBrowserFocus: !this.focusService.isKeyboardMode()
});
}
}
}
destroy() {
this.restoreFocusedCell();
super.destroy();
}
};
// enterprise-modules/menu/src/menu/enterpriseMenu.ts
var import_core8 = require("@ag-grid-community/core");
var import_core9 = require("@ag-grid-enterprise/core");
var TAB_FILTER = "filterMenuTab";
var TAB_GENERAL = "generalMenuTab";
var TAB_COLUMNS = "columnsMenuTab";
var TABS_DEFAULT = [TAB_GENERAL, TAB_FILTER, TAB_COLUMNS];
var EnterpriseMenuFactory = class extends import_core8.BeanStub {
constructor() {
super(...arguments);
this.beanName = "enterpriseMenuFactory";
}
wireBeans(beans) {
this.popupService = beans.popupService;
this.focusService = beans.focusService;
this.ctrlsService = beans.ctrlsService;
this.visibleColsService = beans.visibleColsService;
this.filterManager = beans.filterManager;
this.menuUtils = beans.menuUtils;
this.menuService = beans.menuService;
this.columnMenuFactory = beans.columnMenuFactory;
}
hideActiveMenu() {
this.destroyBean(this.activeMenu);
}
showMenuAfterMouseEvent(columnOrGroup, mouseEvent, containerType, filtersOnly) {
const { column, columnGroup } = this.splitColumnOrGroup(columnOrGroup);
const defaultTab = filtersOnly ? "filterMenuTab" : void 0;
this.showMenu(
column,
columnGroup,
(menu) => {
const ePopup = menu.getGui();
this.popupService.positionPopupUnderMouseEvent({
type: containerType,
column,
mouseEvent,
ePopup
});
if (defaultTab) {
menu.showTab?.(defaultTab);
}
this.dispatchVisibleChangedEvent(true, false, column, columnGroup, defaultTab);
},
containerType,
defaultTab,
void 0,
mouseEvent.target
);
}
splitColumnOrGroup(columnOrGroup) {
const colIsColumn = columnOrGroup && (0, import_core8.isColumn)(columnOrGroup);
const column = colIsColumn ? columnOrGroup : void 0;
const columnGroup = colIsColumn ? void 0 : columnOrGroup;
return { column, columnGroup };
}
showMenuAfterButtonClick(columnOrGroup, eventSource, containerType, filtersOnly) {
let multiplier = -1;
let alignSide = "left";
if (this.gos.get("enableRtl")) {
multiplier = 1;
alignSide = "right";
}
const defaultTab = filtersOnly ? "filterMenuTab" : void 0;
const restrictToTabs = defaultTab ? [defaultTab] : void 0;
const isLegacyMenuEnabled = this.menuService.isLegacyMenuEnabled();
const nudgeX = (isLegacyMenuEnabled ? 9 : 4) * multiplier;
const nudgeY = isLegacyMenuEnabled ? -23 : 4;
const { column, columnGroup } = this.splitColumnOrGroup(columnOrGroup);
this.showMenu(
column,
columnGroup,
(menu) => {
const ePopup = menu.getGui();
this.popupService.positionPopupByComponent({
type: containerType,
column,
eventSource,
ePopup,
alignSide,
nudgeX,
nudgeY,
position: "under",
keepWithinBounds: true
});
if (defaultTab) {
menu.showTab?.(defaultTab);
}
this.dispatchVisibleChangedEvent(true, false, column, columnGroup, defaultTab);
},
containerType,
defaultTab,
restrictToTabs,
eventSource
);
}
showMenu(column, columnGroup, positionCallback, containerType, defaultTab, restrictToTabs, eventSource) {
const menuParams = this.getMenuParams(column, columnGroup, restrictToTabs, eventSource);
if (!menuParams) {
return;
}
const { menu, eMenuGui, anchorToElement, restoreFocusParams } = menuParams;
const closedFuncs = [];
closedFuncs.push((e) => {
const eComp = menu.getGui();
this.destroyBean(menu);
if (column) {
column.setMenuVisible(false, "contextMenu");
this.menuUtils.restoreFocusOnClose(restoreFocusParams, eComp, e);
}
});
const translate = this.localeService.getLocaleTextFunc();
this.popupService.addPopup({
modal: true,
eChild: eMenuGui,
closeOnEsc: true,
closedCallback: (e) => {
closedFuncs.forEach((f) => f(e));
this.dispatchVisibleChangedEvent(false, false, column, columnGroup, defaultTab);
},
afterGuiAttached: (params) => menu.afterGuiAttached(Object.assign({}, { container: containerType }, params)),
// if defaultTab is not present, positionCallback will be called
// after `showTabBasedOnPreviousSelection` is called.
positionCallback: defaultTab ? () => positionCallback(menu) : void 0,
ariaLabel: translate("ariaLabelColumnMenu", "Column Menu")
});
if (!defaultTab) {
menu.showTabBasedOnPreviousSelection?.();
positionCallback(menu);
}
if (this.menuService.isColumnMenuAnchoringEnabled()) {
const stopAnchoringPromise = this.popupService.setPopupPositionRelatedToElement(eMenuGui, anchorToElement);
if (stopAnchoringPromise && column) {
this.addStopAnchoring(stopAnchoringPromise, column, closedFuncs);
}
}
menu.addEventListener("tabSelected", (event) => {
this.dispatchVisibleChangedEvent(false, true, column);
this.lastSelectedTab = event.key;
this.dispatchVisibleChangedEvent(true, true, column);
});
column?.setMenuVisible(true, "contextMenu");
this.activeMenu = menu;
menu.addEventListener("destroyed", () => {
if (this.activeMenu === menu) {
this.activeMenu = null;
}
});
}
addStopAnchoring(stopAnchoringPromise, column, closedFuncsArr) {
stopAnchoringPromise.then((stopAnchoringFunc) => {
column.addEventListener("leftChanged", stopAnchoringFunc);
column.addEventListener("visibleChanged", stopAnchoringFunc);
closedFuncsArr.push(() => {
column.removeEventListener("leftChanged", stopAnchoringFunc);
column.removeEventListener("visibleChanged", stopAnchoringFunc);
});
});
}
getMenuParams(column, columnGroup, restrictToTabs, eventSource) {
const restoreFocusParams = {
column,
headerPosition: this.focusService.getFocusedHeader(),
columnIndex: this.visibleColsService.getAllCols().indexOf(column),
eventSource
};
const menu = this.createMenu(column, columnGroup, restoreFocusParams, restrictToTabs, eventSource);
return menu ? {
menu,
eMenuGui: menu.getGui(),
anchorToElement: eventSource || this.ctrlsService.getGridBodyCtrl().getGui(),
restoreFocusParams
} : void 0;
}
createMenu(column, columnGroup, restoreFocusParams, restrictToTabs, eventSource) {
if (this.menuService.isLegacyMenuEnabled()) {
return this.createBean(
new TabbedColumnMenu(column, restoreFocusParams, this.lastSelectedTab, restrictToTabs, eventSource)
);
} else {
const menuItems = this.columnMenuFactory.getMenuItems(column, columnGroup);
return menuItems.length ? this.createBean(new ColumnContextMenu(menuItems, column, restoreFocusParams, eventSource)) : void 0;
}
}
dispatchVisibleChangedEvent(visible, switchingTab, column, columnGroup, defaultTab) {
this.eventService.dispatchEvent({
type: "columnMenuVisibleChanged",
visible,
switchingTab,
key: this.lastSelectedTab ?? defaultTab ?? (this.menuService.isLegacyMenuEnabled() ? TAB_GENERAL : "columnMenu"),
column: column ?? null,
columnGroup: columnGroup ?? null
});
}
isMenuEnabled(column) {
if (!this.menuService.isLegacyMenuEnabled()) {
return true;
}
const isFilterDisabled = !this.filterManager?.isFilterAllowed(column);
const tabs = column.getColDef().menuTabs ?? TABS_DEFAULT;
const numActiveTabs = isFilterDisabled && tabs.includes(TAB_FILTER) ? tabs.length - 1 : tabs.length;
return numActiveTabs > 0;
}
showMenuAfterContextMenuEvent(column, mouseEvent, touchEvent) {
this.menuUtils.onContextMenu(mouseEvent, touchEvent, (eventOrTouch) => {
this.showMenuAfterMouseEvent(column, eventOrTouch, "columnMenu");
return true;
});
}
};
var TabbedColumnMenu = class extends import_core8.BeanStub {
constructor(column, restoreFocusParams, initialSelection, restrictTo, sourceElement) {
super();
this.column = column;
this.restoreFocusParams = restoreFocusParams;
this.initialSelection = initialSelection;
this.restrictTo = restrictTo;
this.sourceElement = sourceElement;
this.tabFactories = {};
this.includeChecks = {};
this.tabFactories[TAB_GENERAL] = this.createMainPanel.bind(this);
this.tabFactories[TAB_FILTER] = this.createFilterPanel.bind(this);
this.tabFactories[TAB_COLUMNS] = this.createColumnsPanel.bind(this);
this.includeChecks[TAB_GENERAL] = () => true;
this.includeChecks[TAB_FILTER] = () => column ? !!this.filterManager?.isFilterAllowed(column) : false;
this.includeChecks[TAB_COLUMNS] = () => true;
}
wireBeans(beans) {
this.filterManager = beans.filterManager;
this.columnChooserFactory = beans.columnChooserFactory;
this.columnMenuFactory = beans.columnMenuFactory;
this.menuUtils = beans.menuUtils;
}
postConstruct() {
const tabs = this.getTabsToCreate().map((name) => this.createTab(name));
this.tabbedLayout = new import_core9.TabbedLayout({
items: tabs,
cssClass: "ag-menu",
onActiveItemClicked: this.onHidePopup.bind(this),
onItemClicked: this.onTabItemClicked.bind(this)
});
this.createBean(this.tabbedLayout);
if (this.mainMenuList) {
this.mainMenuList.setParentComponent(this.tabbedLayout);
}
this.addDestroyFunc(() => this.destroyBean(this.tabbedLayout));
}
getTabsToCreate() {
if (this.restrictTo) {
return this.restrictTo;
}
return (this.column?.getColDef().menuTabs ?? TABS_DEFAULT).filter((tabName) => this.isValidMenuTabItem(tabName)).filter((tabName) => this.isNotSuppressed(tabName)).filter((tabName) => this.isModuleLoaded(tabName));
}
isModuleLoaded(menuTabName) {
if (menuTabName === TAB_COLUMNS) {
return this.gos.isModuleRegistered(import_core8.ModuleNames.ColumnsToolPanelModule);
}
return true;
}
isValidMenuTabItem(menuTabName) {
let isValid = true;
let itemsToConsider = TABS_DEFAULT;
if (this.restrictTo != null) {
isValid = this.restrictTo.indexOf(menuTabName) > -1;
itemsToConsider = this.restrictTo;
}
isValid = isValid && TABS_DEFAULT.indexOf(menuTabName) > -1;
if (!isValid) {
(0, import_core8._warnOnce)(
`Trying to render an invalid menu item '${menuTabName}'. Check that your 'menuTabs' contains one of [${itemsToConsider}]`
);
}
return isValid;
}
isNotSuppressed(menuTabName) {
return this.includeChecks[menuTabName]();
}
createTab(name) {
return this.tabFactories[name]();
}
showTabBasedOnPreviousSelection() {
this.showTab(this.initialSelection);
}
showTab(toShow) {
if (this.tabItemColumns && toShow === TAB_COLUMNS) {
this.tabbedLayout.showItem(this.tabItemColumns);
} else if (this.tabItemFilter && toShow === TAB_FILTER) {
this.tabbedLayout.showItem(this.tabItemFilter);
} else if (this.tabItemGeneral && toShow === TAB_GENERAL) {
this.tabbedLayout.showItem(this.tabItemGeneral);
} else {
this.tabbedLayout.showFirstItem();
}
}
onTabItemClicked(event) {
let key = null;
switch (event.item) {
case this.tabItemColumns:
key = TAB_COLUMNS;
break;
case this.tabItemFilter:
key = TAB_FILTER;
break;
case this.tabItemGeneral:
key = TAB_GENERAL;
break;
}
if (key) {
this.activateTab(key);
}
}
activateTab(tab) {
const ev = {
type: "tabSelected",
key: tab
};
this.dispatchLocalEvent(ev);
}
createMainPanel() {
this.mainMenuList = this.columnMenuFactory.createMenu(
this,
this.columnMenuFactory.getMenuItems(this.column),
this.column,
() => this.sourceElement ?? this.getGui()
);
this.mainMenuList.addEventListener("closeMenu", this.onHidePopup.bind(this));
this.tabItemGeneral = {
title: (0, import_core8._createIconNoSpan)("menu", this.gos, this.column),
titleLabel: TAB_GENERAL.replace("MenuTab", ""),
bodyPromise: import_core8.AgPromise.resolve(this.mainMenuList.getGui()),
name: TAB_GENERAL
};
return this.tabItemGeneral;
}
onHidePopup(event) {
this.menuUtils.closePopupAndRestoreFocusOnSelect(this.hidePopupFunc, this.restoreFocusParams, event);
}
createFilterPanel() {
const comp = this.column ? this.createBean(new import_core8.FilterWrapperComp(this.column, "COLUMN_MENU")) : null;
this.filterComp = comp;
if (!comp?.hasFilter()) {
throw new Error("AG Grid - Unable to instantiate filter");
}
const afterAttachedCallback = (params) => comp.afterGuiAttached(params);
const afterDetachedCallback = () => comp.afterGuiDetached();
this.tabItemFilter = {
title: (0, import_core8._createIconNoSpan)("filter", this.gos, this.column),
titleLabel: TAB_FILTER.replace("MenuTab", ""),
bodyPromise: import_core8.AgPromise.resolve(comp?.getGui()),
afterAttachedCallback,
afterDetachedCallback,
name: TAB_FILTER
};
return this.tabItemFilter;
}
createColumnsPanel() {
const eWrapperDiv = document.createElement("div");
eWrapperDiv.classList.add("ag-menu-column-select-wrapper");
const columnSelectPanel = this.columnChooserFactory.createColumnSelectPanel(this, this.column);
const columnSelectPanelGui = columnSelectPanel.getGui();
columnSelectPanelGui.classList.add("ag-menu-column-select");
eWrapperDiv.appendChild(columnSelectPanelGui);
this.tabItemColumns = {
title: (0, import_core8._createIconNoSpan)("columns", this.gos, this.column),
//createColumnsIcon(),
titleLabel: TAB_COLUMNS.replace("MenuTab", ""),
bodyPromise: import_core8.AgPromise.resolve(eWrapperDiv),
name: TAB_COLUMNS
};
return this.tabItemColumns;
}
afterGuiAttached(params) {
const { container, hidePopup } = params;
this.tabbedLayout.setAfterAttachedParams({ container, hidePopup });
if (hidePopup) {
this.hidePopupFunc = hidePopup;
this.addDestroyFunc(hidePopup);
}
}
getGui() {
return this.tabbedLayout.getGui();
}
destroy() {
super.destroy();
this.destroyBean(this.filterComp);
}
};
var ColumnContextMenu = class extends import_core8.Component {
constructor(menuItems, column, restoreFocusParams, sourceElement) {
super(
/* html */
`
<div data-ref="eColumnMenu" role="presentation" class="ag-menu ag-column-menu"></div>
`
);
this.menuItems = menuItems;
this.column = column;
this.restoreFocusParams = restoreFocusParams;
this.sourceElement = sourceElement;
this.eColumnMenu = import_core8.RefPlaceholder;
}
wireBeans(beans) {
this.columnMenuFactory = beans.columnMenuFactory;
this.menuUtils = beans.menuUtils;
this.focusService = beans.focusService;
}
postConstruct() {
this.mainMenuList = this.columnMenuFactory.createMenu(
this,
this.menuItems,
this.column,
() => this.sourceElement ?? this.getGui()
);
this.mainMenuList.addEventListener("closeMenu", this.onHidePopup.bind(this));
this.eColumnMenu.appendChild(this.mainMenuList.getGui());
}
onHidePopup(event) {
this.menuUtils.closePopupAndRestoreFocusOnSelect(this.hidePopupFunc, this.restoreFocusParams, event);
}
afterGuiAttached({ hidePopup }) {
if (hidePopup) {
this.hidePopupFunc = hidePopup;
this.addDestroyFunc(hidePopup);
}
this.focusService.focusInto(this.mainMenuList.getGui());
}
};
// enterprise-modules/menu/src/menu/menuApi.ts
function showContextMenu(beans, params) {
const { rowNode, column, value, x, y } = params || {};
let { x: clientX, y: clientY } = beans.menuService.getContextMenuPosition(rowNode, column);
if (x != null) {
clientX = x;
}
if (y != null) {
clientY = y;
}
beans.menuService.showContextMenu({
mouseEvent: new MouseEvent("mousedown", { clientX, clientY }),
rowNode,
column,
value
});
}
function showColumnChooser(beans, params) {
beans.men