devextreme
Version:
JavaScript/TypeScript Component Suite for Responsive Web Development
118 lines (117 loc) • 7.81 kB
JavaScript
/**
* DevExtreme (cjs/__internal/grids/data_grid/ai_assistant/commands/summary.js)
* Version: 26.1.3
* Build date: Wed Jun 10 2026
*
* Copyright (c) 2012 - 2026 Developer Express Inc. ALL RIGHTS RESERVED
* Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
*/
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.summaryCommand = exports.clearSummaryCommand = void 0;
var _defineGridCommand = require("../../../../grids/grid_core/ai_assistant/commands/defineGridCommand");
var _utils = require("../../../../grids/grid_core/ai_assistant/commands/utils");
var _zod = require("zod");
const SUMMARY_TYPES = ["sum", "min", "max", "avg", "count"];
const summaryItemBaseShape = {
column: _zod.z.string(),
summaryType: _zod.z.enum(SUMMARY_TYPES),
showInColumn: (0, _utils.optionalNullish)(_zod.z.string()),
displayFormat: (0, _utils.optionalNullish)(_zod.z.string())
};
const totalItemSchema = _zod.z.object(summaryItemBaseShape).strict();
const groupItemSchema = _zod.z.object(Object.assign({}, summaryItemBaseShape, {
showInGroupFooter: (0, _utils.optionalNullish)(_zod.z.boolean()),
alignByColumn: (0, _utils.optionalNullish)(_zod.z.boolean())
})).strict();
const summaryCommandSchema = _zod.z.object({
totalItems: _zod.z.array(totalItemSchema),
groupItems: _zod.z.array(groupItemSchema)
}).strict();
const SUMMARY_TYPE_LABELS = {
sum: "sum",
min: "minimum",
max: "maximum",
avg: "average",
count: "count"
};
const buildItemLabel = (item, location, columnsController) => {
const column = columnsController.columnOption(item.column);
const caption = (null === column || void 0 === column ? void 0 : column.caption) ?? item.column;
return `"${caption}" ${SUMMARY_TYPE_LABELS[item.summaryType]} (${location})`
};
const buildDefaultMessage = (totalItems, groupItems, columnsController) => {
if (0 === totalItems.length && 0 === groupItems.length) {
return "Display data summaries."
}
const labels = [...totalItems.map(it => buildItemLabel(it, "total", columnsController)), ...groupItems.map(it => buildItemLabel(it, "group", columnsController))];
return `Display data summaries: ${labels.join(", ")}.`
};
const summaryCommand = exports.summaryCommand = (0, _defineGridCommand.defineGridCommand)({
name: "summary",
description: 'Configure column summaries. totalItems aggregate the entire data set; groupItems aggregate within each group. Replaces the configuration entirely \u2014 both kinds are written every call. ALWAYS provide BOTH totalItems and groupItems; pass an explicit empty array [] for a kind to clear it. To keep one kind unchanged, copy its current items from the grid context into your args. To ADD items, pre-merge with the kind\'s current items. To REMOVE a specific item, pass the kind\'s remaining items (and copy the other kind unchanged). At least one kind must be non-empty. Use clearSummary only when EVERY summary should be removed.\nEach item supports:\n- column (required): dataField of the column whose VALUES are aggregated. Phrases like "sum of X", "average X", "total X", "summary for X" \u2192 column="X" (X is what gets aggregated).\n- summaryType (required): one of "sum", "min", "max", "avg", "count".\n- showInColumn (optional): dataField of the column where the value is DISPLAYED (not aggregated). OMIT unless the user explicitly names a second column with a phrase like "show in Y", "display under Y", "in the Y column" \u2192 showInColumn="Y". Example: "sum of Amount in the SaleDate column" \u2192 column="Amount", showInColumn="SaleDate". One column mentioned \u2192 OMIT. For totalItems, controls which footer cell shows the value. For groupItems, showInColumn has effect ONLY when paired with showInGroupFooter=true OR alignByColumn=true \u2014 so whenever you set showInColumn on a group item, you MUST also set alignByColumn=true (the default pairing), unless the user explicitly asked for footer placement (then set showInGroupFooter=true instead).\n- displayFormat (optional): format template for the rendered value. Placeholders: "{0}" \u2014 the formatted summary value; "{1}" \u2014 the parent column\'s caption (for group items only resolvable when showInColumn is specified). Example: "Sum: {0}" or "{1}: {0}".\nGroup items additionally support:\n- showInGroupFooter (optional): OMIT this field unless the user explicitly requests the group footer area. Default behavior renders the summary in the group row (the header that displays the group value). Set to true ONLY when the user explicitly says "group footer", "below the group", or "in the footer". Requests like "in the header", "in the group row", "next to the group name", or no placement mention at all \u2192 OMIT (do not set to false either; just omit the field).\n- alignByColumn (optional): OMIT this field unless the user explicitly requests column-aligned layout. Default behavior lists items in parentheses after the group row caption (e.g. "Category: Bikes (Sum: 100, Count: 5)"). Set to true ONLY when the user explicitly asks to "align by column", "show under each column", or "align with the column". Otherwise OMIT.',
schema: summaryCommandSchema,
execute: (component, _ref) => {
let {
success: success,
failure: failure
} = _ref;
return args => {
const columnsController = component.getController("columns");
const {
totalItems: totalItems,
groupItems: groupItems
} = args;
const allItems = [...totalItems, ...groupItems];
const defaultMessage = buildDefaultMessage(totalItems, groupItems, columnsController);
if (0 === allItems.length) {
return Promise.resolve(failure(defaultMessage))
}
const allColumnsResolve = allItems.every(item => {
if (void 0 === columnsController.columnOption(item.column)) {
return false
}
if (void 0 !== item.showInColumn) {
return void 0 !== columnsController.columnOption(item.showInColumn)
}
return true
});
if (!allColumnsResolve) {
return Promise.resolve(failure(defaultMessage))
}
try {
component.option("summary", {
totalItems: totalItems,
groupItems: groupItems
});
return Promise.resolve(success(defaultMessage))
} catch {
return Promise.resolve(failure(defaultMessage))
}
}
}
});
const clearSummaryCommand = exports.clearSummaryCommand = (0, _defineGridCommand.defineGridCommand)({
name: "clearSummary",
description: "Remove ALL summary items. Do NOT call this for partial removals. Use only when every summary should be cleared (both totalItems and groupItems). To remove a subset \u2014 e.g., clear only totalItems while keeping groupItems (or vice versa), or drop a specific item \u2014 call the summary command with the items that should remain, since summary replaces existing summaries entirely.",
schema: _zod.z.object({}).strict(),
execute: (component, _ref2) => {
let {
success: success,
failure: failure
} = _ref2;
return () => {
try {
component.option("summary", {
groupItems: [],
totalItems: []
});
return Promise.resolve(success("Clear column summaries."))
} catch {
return Promise.resolve(failure("Clear column summaries."))
}
}
}
});