UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

454 lines (453 loc) • 17.5 kB
/** * DevExtreme (esm/ui/scheduler/resources/resourceManager.js) * Version: 21.1.4 * Build date: Mon Jun 21 2021 * * Copyright (c) 2012 - 2021 Developer Express Inc. ALL RIGHTS RESERVED * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/ */ import { wrapToArray, inArray } from "../../../core/utils/array"; import { grep } from "../../../core/utils/common"; import { isDefined } from "../../../core/utils/type"; import { deepExtendArraySafe } from "../../../core/utils/object"; import { each, map } from "../../../core/utils/iterator"; import { extend } from "../../../core/utils/extend"; import query from "../../../data/query"; import { compileGetter, compileSetter } from "../../../core/utils/data"; import { when, Deferred } from "../../../core/utils/deferred"; import { AgendaResourceProcessor } from "./agendaResourceProcessor"; import { getDisplayExpr, getFieldExpr, getValueExpr, getWrappedDataSource } from "./utils"; export class ResourceManager { constructor(resources) { this._resourceLoader = {}; this.agendaProcessor = new AgendaResourceProcessor; this.setResources(resources) } _mapResourceData(resource, data) { var valueGetter = compileGetter(getValueExpr(resource)); var displayGetter = compileGetter(getDisplayExpr(resource)); return map(data, (function(item) { var result = { id: valueGetter(item), text: displayGetter(item) }; if (item.color) { result.color = item.color } return result })) } _isMultipleResource(resourceField) { var result = false; each(this.getResources(), function(_, resource) { var field = getFieldExpr(resource); if (field === resourceField) { result = resource.allowMultiple; return false } }.bind(this)); return result } getDataAccessors(field, type) { var result = null; each(this._dataAccessors[type], (function(accessorName, accessors) { if (field === accessorName) { result = accessors; return false } })); return result } setResources(resources) { this._resources = resources; this._dataAccessors = { getter: {}, setter: {} }; this._resourceFields = map(resources || [], function(resource) { var field = getFieldExpr(resource); this._dataAccessors.getter[field] = compileGetter(field); this._dataAccessors.setter[field] = compileSetter(field); return field }.bind(this)); this.agendaProcessor.initializeState(resources) } getResources() { return this._resources || [] } getResourcesData() { return this._resourcesData || [] } getEditors() { var result = []; var that = this; each(this.getResources(), (function(i, resource) { var field = getFieldExpr(resource); var currentResourceItems = that._getResourceDataByField(field); result.push({ editorOptions: { dataSource: currentResourceItems.length ? currentResourceItems : getWrappedDataSource(resource.dataSource), displayExpr: getDisplayExpr(resource), valueExpr: getValueExpr(resource) }, dataField: field, editorType: resource.allowMultiple ? "dxTagBox" : "dxSelectBox", label: { text: resource.label || field } }) })); return result } getResourceDataByValue(field, value) { var that = this; var result = new Deferred; each(this.getResources(), (function(_, resource) { var resourceField = getFieldExpr(resource); if (resourceField === field) { var dataSource = getWrappedDataSource(resource.dataSource); var valueExpr = getValueExpr(resource); if (!that._resourceLoader[field]) { that._resourceLoader[field] = dataSource.load() } that._resourceLoader[field].done((function(data) { var filteredData = query(data).filter(valueExpr, value).toArray(); delete that._resourceLoader[field]; result.resolve(filteredData[0]) })).fail((function() { delete that._resourceLoader[field]; result.reject() })); return false } })); return result.promise() } setResourcesToItem(itemData, resources) { var resourcesSetter = this._dataAccessors.setter; for (var name in resources) { if (Object.prototype.hasOwnProperty.call(resources, name)) { var resourceData = resources[name]; resourcesSetter[name](itemData, this._isMultipleResource(name) ? wrapToArray(resourceData) : resourceData) } } } getResourcesFromItem(itemData, wrapOnlyMultipleResources) { var result = null; if (!isDefined(wrapOnlyMultipleResources)) { wrapOnlyMultipleResources = false } this._resourceFields.forEach(field => { each(itemData, (fieldName, fieldValue) => { var tempObject = {}; tempObject[fieldName] = fieldValue; var resourceData = this.getDataAccessors(field, "getter")(tempObject); if (isDefined(resourceData)) { if (!result) { result = {} } if (1 === resourceData.length) { resourceData = resourceData[0] } if (!wrapOnlyMultipleResources || wrapOnlyMultipleResources && this._isMultipleResource(field)) { this.getDataAccessors(field, "setter")(tempObject, wrapToArray(resourceData)) } else { this.getDataAccessors(field, "setter")(tempObject, resourceData) } extend(result, tempObject); return true } }) }); return result } loadResources(groups) { var result = new Deferred; var that = this; var deferreds = []; each(this.getResourcesByFields(groups), (function(i, resource) { var deferred = new Deferred; var field = getFieldExpr(resource); deferreds.push(deferred); getWrappedDataSource(resource.dataSource).load().done((function(data) { deferred.resolve({ name: field, items: that._mapResourceData(resource, data), data: data }) })).fail((function() { deferred.reject() })) })); if (!deferreds.length) { that._resourcesData = []; return result.resolve([]) } when.apply(null, deferreds).done((function() { var data = Array.prototype.slice.call(arguments); var mapFunction = function(obj) { return { name: obj.name, items: obj.items, data: obj.data } }; var isValidResources = that._isValidResourcesForGrouping(data); that._resourcesData = isValidResources ? data : []; result.resolve(isValidResources ? data.map(mapFunction) : []) })).fail((function() { result.reject() })); return result.promise() } getResourcesByFields(fields) { return grep(this.getResources(), function(resource) { var field = getFieldExpr(resource); return inArray(field, fields) > -1 }.bind(this)) } getResourceByField(field) { return this.getResourcesByFields([field])[0] || {} } getResourceColor(field, value) { var valueExpr = this.getResourceByField(field).valueExpr || "id"; var valueGetter = compileGetter(valueExpr); var colorExpr = this.getResourceByField(field).colorExpr || "color"; var colorGetter = compileGetter(colorExpr); var result = new Deferred; var resourceData = this._getResourceDataByField(field); var resourceDataLength = resourceData.length; var color; if (resourceDataLength) { for (var i = 0; i < resourceDataLength; i++) { if (valueGetter(resourceData[i]) === value) { color = colorGetter(resourceData[i]); break } } result.resolve(color) } else { this.getResourceDataByValue(field, value).done((function(resourceData) { if (resourceData) { color = colorGetter(resourceData) } result.resolve(color) })).fail((function() { result.reject() })) } return result.promise() } getResourceForPainting(groups) { var resources = this.getResources(); var result; each(resources, (function(index, resource) { if (resource.useColorAsDefault) { result = resource; return false } })); if (!result) { if (Array.isArray(groups) && groups.length) { resources = this.getResourcesByFields(groups) } result = resources[resources.length - 1] } return result } createResourcesTree(groups) { var leafIndex = 0; return function make(group, groupIndex, result, parent) { result = result || []; for (var i = 0; i < group.items.length; i++) { var currentGroupItem = group.items[i]; var resultItem = { name: group.name, value: currentGroupItem.id, title: currentGroupItem.text, data: group.data && group.data[i], children: [], parent: parent ? parent : null }; result.push(resultItem); var nextGroupIndex = groupIndex + 1; if (groups[nextGroupIndex]) { make.call(this, groups[nextGroupIndex], nextGroupIndex, resultItem.children, resultItem) } if (!resultItem.children.length) { resultItem.leafIndex = leafIndex; leafIndex++ } } return result }.call(this, groups[0], 0) } _hasGroupItem(appointmentResources, groupName, itemValue) { var group = this.getDataAccessors(groupName, "getter")(appointmentResources); if (group) { if (inArray(itemValue, group) > -1) { return true } } return false } _createPlainResourcesByAppointmentAsync(rawAppointment) { return this.agendaProcessor.createListAsync(rawAppointment) } _getResourceDataByField(fieldName) { var loadedResources = this.getResourcesData(); var currentResourceData = []; for (var i = 0, resourceCount = loadedResources.length; i < resourceCount; i++) { if (loadedResources[i].name === fieldName) { currentResourceData = loadedResources[i].data; break } } return currentResourceData } getResourceTreeLeaves(tree, appointmentResources, result) { result = result || []; for (var i = 0; i < tree.length; i++) { if (!this._hasGroupItem(appointmentResources, tree[i].name, tree[i].value)) { continue } if (isDefined(tree[i].leafIndex)) { result.push(tree[i].leafIndex) } if (tree[i].children) { this.getResourceTreeLeaves(tree[i].children, appointmentResources, result) } } return result } groupAppointmentsByResources(appointments, resources) { var tree = this.createResourcesTree(resources); var result = {}; each(appointments, function(_, appointment) { var appointmentResources = this.getResourcesFromItem(appointment); var treeLeaves = this.getResourceTreeLeaves(tree, appointmentResources); for (var i = 0; i < treeLeaves.length; i++) { if (!result[treeLeaves[i]]) { result[treeLeaves[i]] = [] } result[treeLeaves[i]].push(deepExtendArraySafe({}, appointment, true)) } }.bind(this)); return result } reduceResourcesTree(tree, existingAppointments, _result) { _result = _result ? _result.children : []; var that = this; tree.forEach((function(node, index) { var ok = false; var resourceName = node.name; var resourceValue = node.value; var resourceTitle = node.title; var resourceData = node.data; var resourceGetter = that.getDataAccessors(resourceName, "getter"); existingAppointments.forEach((function(appointment) { if (!ok) { var resourceFromAppointment = resourceGetter(appointment); if (Array.isArray(resourceFromAppointment)) { if (resourceFromAppointment.indexOf(resourceValue) > -1) { _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) { that.reduceResourcesTree(node.children, existingAppointments, _result[index]) } })); return _result } getResourcesDataByGroups(groups) { var resourcesData = this.getResourcesData(); if (!groups || !groups.length) { return resourcesData } var fieldNames = {}; var currentResourcesData = []; groups.forEach(group => { each(group, (name, value) => fieldNames[name] = value) }); var resourceData = resourcesData.filter(_ref => { var { name: name } = _ref; return isDefined(fieldNames[name]) }); resourceData.forEach(data => currentResourcesData.push(extend({}, data))); currentResourcesData.forEach(currentResource => { var { items: items, data: data, name: resourceName } = currentResource; var resource = this.getResourceByField(resourceName); var valueExpr = getValueExpr(resource); var filteredItems = []; var filteredData = []; groups.filter(group => isDefined(group[resourceName])).forEach(group => { each(group, (name, value) => { if (!filteredItems.filter(item => item.id === value && item[valueExpr] === name).length) { var currentItems = items.filter(item => item.id === value); var currentData = data.filter(item => item[valueExpr] === value); filteredItems.push(...currentItems); filteredData.push(...currentData) } }) }); currentResource.items = filteredItems; currentResource.data = filteredData }); return currentResourcesData } _isValidResourcesForGrouping(resources) { var result = resources.reduce((isValidResources, currentResource) => isValidResources && currentResource.items.length > 0, true); return result } }