UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

499 lines (497 loc) • 21.3 kB
/** * DevExtreme (cjs/__internal/scheduler/resources/m_utils.js) * Version: 24.2.6 * Build date: Mon Mar 17 2025 * * Copyright (c) 2012 - 2025 Developer Express Inc. ALL RIGHTS RESERVED * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/ */ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.setResourceToAppointment = exports.reduceResourcesTree = exports.loadResources = exports.isResourceMultiple = exports.groupAppointmentsByResourcesCore = exports.groupAppointmentsByResources = exports.getWrappedDataSource = exports.getValueExpr = exports.getResourcesDataByGroups = exports.getResourceTreeLeaves = exports.getResourceColor = exports.getResourceByField = exports.getPathToLeaf = exports.getPaintedResources = exports.getOrLoadResourceItem = exports.getNormalizedResources = exports.getGroupsObjectFromGroupsArray = exports.getFieldExpr = exports.getDisplayExpr = exports.getDataAccessors = exports.getCellGroups = exports.getAppointmentColor = exports.getAllGroups = exports.filterResources = exports.createResourcesTree = exports.createResourceEditorModel = exports.createReducedResourcesTree = exports.createExpressions = void 0; var _data_source = require("../../../common/data/data_source/data_source"); var _utils = require("../../../common/data/data_source/utils"); var _array = require("../../../core/utils/array"); var _common = require("../../../core/utils/common"); var _data = require("../../../core/utils/data"); var _deferred = require("../../../core/utils/deferred"); var _extend = require("../../../core/utils/extend"); var _iterator = require("../../../core/utils/iterator"); var _object = require("../../../core/utils/object"); var _type = require("../../../core/utils/type"); var _themes = require("../../../ui/themes"); var _index = require("../../scheduler/r1/utils/index"); function _extends() { return _extends = Object.assign ? Object.assign.bind() : function(n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) { ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]) } } return n }, _extends.apply(null, arguments) } const getValueExpr = resource => resource.valueExpr || "id"; exports.getValueExpr = getValueExpr; const getDisplayExpr = resource => resource.displayExpr || "text"; exports.getDisplayExpr = getDisplayExpr; const getFieldExpr = resource => resource.fieldExpr || resource.field; exports.getFieldExpr = getFieldExpr; const getWrappedDataSource = dataSource => { if (dataSource instanceof _data_source.DataSource) { return dataSource } const result = _extends({}, (0, _utils.normalizeDataSourceOptions)(dataSource), { pageSize: 0 }); if (!Array.isArray(dataSource)) { result.filter = dataSource.filter } return new _data_source.DataSource(result) }; exports.getWrappedDataSource = getWrappedDataSource; const createResourcesTree = groups => { let leafIndex = 0; const make = (group, groupIndex, result, parent) => { result = result || []; for (let itemIndex = 0; itemIndex < group.items.length; itemIndex++) { var _group$data; const currentGroupItem = group.items[itemIndex]; const resultItem = { name: group.name, value: currentGroupItem.id, title: currentGroupItem.text, data: null === (_group$data = group.data) || void 0 === _group$data ? void 0 : _group$data[itemIndex], children: [], parent: parent || null }; const nextGroupIndex = groupIndex + 1; if (groups[nextGroupIndex]) { make(groups[nextGroupIndex], nextGroupIndex, resultItem.children, resultItem) } if (!resultItem.children.length) { resultItem.leafIndex = leafIndex; leafIndex++ } result.push(resultItem) } return result }; return make(groups[0], 0) }; exports.createResourcesTree = createResourcesTree; const getPathToLeaf = (leafIndex, groups) => { const tree = createResourcesTree(groups); const findLeafByIndex = (data, index) => { for (let i = 0; i < data.length; i++) { if (data[i].leafIndex === index) { return data[i] } const leaf = findLeafByIndex(data[i].children, index); if (leaf) { return leaf } } }; const makeBranch = (leaf, result) => { result = result || []; result.push(leaf.value); if (leaf.parent) { makeBranch(leaf.parent, result) } return result }; const leaf = findLeafByIndex(tree, leafIndex); return makeBranch(leaf).reverse() }; exports.getPathToLeaf = getPathToLeaf; const getCellGroups = (groupIndex, groups) => { const result = []; if ((0, _index.getGroupCount)(groups)) { if (groupIndex < 0) { return } const path = getPathToLeaf(groupIndex, groups); for (let i = 0; i < groups.length; i++) { result.push({ name: groups[i].name, id: path[i] }) } } return result }; exports.getCellGroups = getCellGroups; const getGroupsObjectFromGroupsArray = groupsArray => groupsArray.reduce(((currentGroups, _ref) => { let { name: name, id: id } = _ref; return _extends({}, currentGroups, { [name]: id }) }), {}); exports.getGroupsObjectFromGroupsArray = getGroupsObjectFromGroupsArray; const getAllGroups = groups => { const groupCount = (0, _index.getGroupCount)(groups); return [...new Array(groupCount)].map(((_, groupIndex) => { const groupsArray = getCellGroups(groupIndex, groups); return getGroupsObjectFromGroupsArray(groupsArray) })) }; exports.getAllGroups = getAllGroups; const getResourceByField = (fieldName, loadedResources) => { for (let i = 0; i < loadedResources.length; i++) { const resource = loadedResources[i]; if (resource.name === fieldName) { return resource.data } } return [] }; exports.getResourceByField = getResourceByField; const createResourceEditorModel = (resources, loadedResources) => resources.map((resource => { const dataField = getFieldExpr(resource); const dataSource = getResourceByField(dataField, loadedResources); return { editorOptions: { dataSource: dataSource.length ? dataSource : getWrappedDataSource(resource.dataSource), displayExpr: getDisplayExpr(resource), valueExpr: getValueExpr(resource), stylingMode: (0, _themes.isFluent)((0, _themes.current)()) ? "filled" : "outlined" }, dataField: dataField, editorType: resource.allowMultiple ? "dxTagBox" : "dxSelectBox", label: { text: resource.label || dataField } } })); exports.createResourceEditorModel = createResourceEditorModel; const isResourceMultiple = (resources, resourceField) => { const resource = resources.find((resource => { const field = getFieldExpr(resource); return field === resourceField })); return !!(null !== resource && void 0 !== resource && resource.allowMultiple) }; exports.isResourceMultiple = isResourceMultiple; const filterResources = (resources, fields) => resources.filter((resource => { const field = getFieldExpr(resource); return fields.indexOf(field) > -1 })); exports.filterResources = filterResources; const getPaintedResources = (resources, groups) => { const newGroups = groups || []; const result = resources.find((resource => resource.useColorAsDefault)); if (result) { return result } const newResources = newGroups.length ? filterResources(resources, newGroups) : resources; return newResources[newResources.length - 1] }; exports.getPaintedResources = getPaintedResources; const getOrLoadResourceItem = (resources, resourceLoaderMap, field, value) => { const result = new _deferred.Deferred; resources.filter((resource => getFieldExpr(resource) === field && (0, _type.isDefined)(resource.dataSource))).forEach((resource => { const wrappedDataSource = getWrappedDataSource(resource.dataSource); const valueExpr = getValueExpr(resource); if (!resourceLoaderMap.has(field)) { resourceLoaderMap.set(field, wrappedDataSource.load()) } resourceLoaderMap.get(field).done((data => { const getter = (0, _data.compileGetter)(valueExpr); const filteredData = data.filter((resource => (0, _common.equalByValue)(getter(resource), value))); result.resolve(filteredData[0]) })).fail((() => { resourceLoaderMap.delete(field); result.reject() })) })); return result.promise() }; exports.getOrLoadResourceItem = getOrLoadResourceItem; const getDataAccessors = (dataAccessors, fieldName, type) => { const actions = dataAccessors[type]; return actions[fieldName] }; exports.getDataAccessors = getDataAccessors; const groupAppointmentsByResources = function(config, appointments) { let groups = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : []; let result = { 0: appointments }; if (groups.length && config.loadedResources.length) { result = groupAppointmentsByResourcesCore(config, appointments, config.loadedResources) } let totalResourceCount = 0; config.loadedResources.forEach(((resource, index) => { if (!index) { totalResourceCount = resource.items.length } else { totalResourceCount *= resource.items.length } })); for (let index = 0; index < totalResourceCount; index++) { const key = index.toString(); if (result[key]) { continue } result[key] = [] } return result }; exports.groupAppointmentsByResources = groupAppointmentsByResources; const groupAppointmentsByResourcesCore = (config, appointments, resources) => { const tree = createResourcesTree(resources); const result = {}; appointments.forEach((appointment => { const treeLeaves = getResourceTreeLeaves(((field, action) => getDataAccessors(config.dataAccessors, field, action)), tree, appointment); for (let i = 0; i < treeLeaves.length; i++) { if (!result[treeLeaves[i]]) { result[treeLeaves[i]] = [] } result[treeLeaves[i]].push((0, _object.deepExtendArraySafe)({}, appointment, true)) } })); return result }; exports.groupAppointmentsByResourcesCore = groupAppointmentsByResourcesCore; const getResourceTreeLeaves = (getDataAccessors, tree, rawAppointment, result) => { result = result || []; for (let i = 0; i < tree.length; i++) { if (!hasGroupItem(getDataAccessors, rawAppointment, tree[i].name, tree[i].value)) { continue } if ((0, _type.isDefined)(tree[i].leafIndex)) { result.push(tree[i].leafIndex) } if (tree[i].children) { getResourceTreeLeaves(getDataAccessors, tree[i].children, rawAppointment, result) } } return result }; exports.getResourceTreeLeaves = getResourceTreeLeaves; const hasGroupItem = (getDataAccessors, rawAppointment, groupName, itemValue) => { const resourceValue = getDataAccessors(groupName, "getter")(rawAppointment); return (0, _index.hasResourceValue)((0, _array.wrapToArray)(resourceValue), itemValue) }; const createReducedResourcesTree = (loadedResources, getDataAccessors, appointments) => { const tree = createResourcesTree(loadedResources); return reduceResourcesTree(getDataAccessors, tree, appointments) }; exports.createReducedResourcesTree = createReducedResourcesTree; const reduceResourcesTree = (getDataAccessors, tree, existingAppointments, _result) => { _result = _result ? _result.children : []; tree.forEach(((node, index) => { let ok = false; const resourceName = node.name; const resourceValue = node.value; const resourceTitle = node.title; const resourceData = node.data; const resourceGetter = getDataAccessors(resourceName, "getter"); existingAppointments.forEach((appointment => { if (!ok) { const resourceFromAppointment = resourceGetter(appointment); if (Array.isArray(resourceFromAppointment)) { if (resourceFromAppointment.includes(resourceValue)) { _result.push({ name: resourceName, value: resourceValue, title: resourceTitle, data: resourceData, children: [] }); ok = true } } else if (resourceFromAppointment === resourceValue) { _result.push({ name: resourceName, value: resourceValue, title: resourceTitle, data: resourceData, children: [] }); ok = true } } })); if (ok && node.children && node.children.length) { reduceResourcesTree(getDataAccessors, node.children, existingAppointments, _result[index]) } })); return _result }; exports.reduceResourcesTree = reduceResourcesTree; const getResourcesDataByGroups = (loadedResources, resources, groups) => { if (!groups || !groups.length) { return loadedResources } const fieldNames = {}; const currentResourcesData = []; groups.forEach((group => { (0, _iterator.each)(group, ((name, value) => { fieldNames[name] = value })) })); const resourceData = loadedResources.filter((_ref2 => { let { name: name } = _ref2; return (0, _type.isDefined)(fieldNames[name]) })); resourceData.forEach((data => currentResourcesData.push((0, _extend.extend)({}, data)))); currentResourcesData.forEach((currentResource => { const { items: items, data: data, name: resourceName } = currentResource; const resource = filterResources(resources, [resourceName])[0] || {}; const valueExpr = getValueExpr(resource); const filteredItems = []; const filteredData = []; groups.filter((group => (0, _type.isDefined)(group[resourceName]))).forEach((group => { (0, _iterator.each)(group, ((name, value) => { if (!filteredItems.filter((item => item.id === value && item[valueExpr] === name)).length) { const currentItems = items.filter((item => item.id === value)); const currentData = data.filter((item => item[valueExpr] === value)); filteredItems.push(...currentItems); filteredData.push(...currentData) } })) })); currentResource.items = filteredItems; currentResource.data = filteredData })); return currentResourcesData }; exports.getResourcesDataByGroups = getResourcesDataByGroups; const setResourceToAppointment = (resources, dataAccessors, appointment, groups) => { const resourcesSetter = dataAccessors.setter; for (const name in groups) { const resourceData = groups[name]; const value = isResourceMultiple(resources, name) ? (0, _array.wrapToArray)(resourceData) : resourceData; resourcesSetter[name](appointment, value) } }; exports.setResourceToAppointment = setResourceToAppointment; const getResourceColor = (resources, resourceLoaderMap, field, value) => { const result = new _deferred.Deferred; const resource = filterResources(resources, [field])[0] || {}; const colorExpr = resource.colorExpr || "color"; const colorGetter = (0, _data.compileGetter)(colorExpr); getOrLoadResourceItem(resources, resourceLoaderMap, field, value).done((resource => result.resolve(colorGetter(resource)))).fail((() => result.reject())); return result.promise() }; exports.getResourceColor = getResourceColor; const getAppointmentColor = (resourceConfig, appointmentConfig) => { const { resources: resources, dataAccessors: dataAccessors, loadedResources: loadedResources, resourceLoaderMap: resourceLoaderMap } = resourceConfig; const { groupIndex: groupIndex, groups: groups, itemData: itemData } = appointmentConfig; const paintedResources = getPaintedResources(resources || [], groups); if (paintedResources) { const field = getFieldExpr(paintedResources); const cellGroups = getCellGroups(groupIndex, loadedResources); const resourcesDataAccessors = getDataAccessors(dataAccessors, field, "getter"); const resourceValues = (0, _array.wrapToArray)(resourcesDataAccessors(itemData)); let groupId = resourceValues[0]; for (let i = 0; i < cellGroups.length; i++) { if (cellGroups[i].name === field) { groupId = cellGroups[i].id; break } } return getResourceColor(resources, resourceLoaderMap, field, groupId) } return (new _deferred.Deferred).resolve().promise() }; exports.getAppointmentColor = getAppointmentColor; const createExpressions = function() { let resources = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : []; const result = { getter: {}, setter: {} }; resources.forEach((resource => { const field = getFieldExpr(resource); result.getter[field] = (0, _data.compileGetter)(field); result.setter[field] = (0, _data.compileSetter)(field) })); return result }; exports.createExpressions = createExpressions; const getTransformedResourceData = (resource, data) => { const valueGetter = (0, _data.compileGetter)(getValueExpr(resource)); const displayGetter = (0, _data.compileGetter)(getDisplayExpr(resource)); return data.map((item => { const result = { id: valueGetter(item), text: displayGetter(item) }; if (item.color) { result.color = item.color } return result })) }; const loadResources = (groups, resources, resourceLoaderMap) => { const result = new _deferred.Deferred; const deferreds = []; const newGroups = groups || []; const newResources = resources || []; let loadedResources = []; filterResources(newResources, newGroups).forEach((resource => { const deferred = new _deferred.Deferred; const name = getFieldExpr(resource); deferreds.push(deferred); const dataSourcePromise = getWrappedDataSource(resource.dataSource).load(); resourceLoaderMap.set(name, dataSourcePromise); dataSourcePromise.done((data => { const items = getTransformedResourceData(resource, data); deferred.resolve({ name: name, items: items, data: data }) })).fail((() => deferred.reject())) })); if (!deferreds.length) { return result.resolve(loadedResources) } _deferred.when.apply(null, deferreds).done((function() { for (var _len = arguments.length, resources = new Array(_len), _key = 0; _key < _len; _key++) { resources[_key] = arguments[_key] } const hasEmpty = resources.some((r => 0 === r.items.length)); loadedResources = hasEmpty ? [] : resources; result.resolve(loadedResources) })).fail((() => result.reject())); return result.promise() }; exports.loadResources = loadResources; const getNormalizedResources = (rawAppointment, dataAccessors, resources) => { const result = {}; (0, _iterator.each)(dataAccessors.resources.getter, (fieldName => { const value = dataAccessors.resources.getter[fieldName](rawAppointment); if ((0, _type.isDefined)(value)) { const isMultiple = isResourceMultiple(resources, fieldName); const resourceValue = isMultiple ? (0, _array.wrapToArray)(value) : value; result[fieldName] = resourceValue } })); return result }; exports.getNormalizedResources = getNormalizedResources;