Skip to content
Snippets Groups Projects
Select Git revision
  • 5825e5dba4c74d216f6f0662a7c8cfdbf1512327
  • main default protected
  • renovate/django-debug-toolbar-6.x
  • renovate/jsonschema-4.x
  • renovate/django-5.x
  • koma/feature/preference-polling-form
6 results

main.js

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    main.js 49.85 KiB
    /*!
    FullCalendar Resource Timeline Plugin v4.3.0
    Docs & License: https://fullcalendar.io/scheduler
    (c) 2019 Adam Shaw
    */
    
    (function (global, factory) {
        typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@fullcalendar/core'), require('@fullcalendar/timeline'), require('@fullcalendar/resource-common')) :
        typeof define === 'function' && define.amd ? define(['exports', '@fullcalendar/core', '@fullcalendar/timeline', '@fullcalendar/resource-common'], factory) :
        (global = global || self, factory(global.FullCalendarResourceTimeline = {}, global.FullCalendar, global.FullCalendarTimeline, global.FullCalendarResourceCommon));
    }(this, function (exports, core, TimelinePlugin, ResourceCommonPlugin) { 'use strict';
    
        var TimelinePlugin__default = 'default' in TimelinePlugin ? TimelinePlugin['default'] : TimelinePlugin;
        var ResourceCommonPlugin__default = 'default' in ResourceCommonPlugin ? ResourceCommonPlugin['default'] : ResourceCommonPlugin;
    
        /*! *****************************************************************************
        Copyright (c) Microsoft Corporation. All rights reserved.
        Licensed under the Apache License, Version 2.0 (the "License"); you may not use
        this file except in compliance with the License. You may obtain a copy of the
        License at http://www.apache.org/licenses/LICENSE-2.0
    
        THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
        KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
        WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
        MERCHANTABLITY OR NON-INFRINGEMENT.
    
        See the Apache Version 2.0 License for specific language governing permissions
        and limitations under the License.
        ***************************************************************************** */
        /* global Reflect, Promise */
    
        var extendStatics = function(d, b) {
            extendStatics = Object.setPrototypeOf ||
                ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
                function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
            return extendStatics(d, b);
        };
    
        function __extends(d, b) {
            extendStatics(d, b);
            function __() { this.constructor = d; }
            d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
        }
    
        var __assign = function() {
            __assign = Object.assign || function __assign(t) {
                for (var s, i = 1, n = arguments.length; i < n; i++) {
                    s = arguments[i];
                    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
                }
                return t;
            };
            return __assign.apply(this, arguments);
        };
    
        var Row = /** @class */ (function (_super) {
            __extends(Row, _super);
            function Row(context, spreadsheetParent, spreadsheetNextSibling, timeAxisParent, timeAxisNextSibling) {
                var _this = _super.call(this, context) || this;
                _this.isSizeDirty = false;
                spreadsheetParent.insertBefore(_this.spreadsheetTr = document.createElement('tr'), spreadsheetNextSibling);
                timeAxisParent.insertBefore(_this.timeAxisTr = document.createElement('tr'), timeAxisNextSibling);
                return _this;
            }
            Row.prototype.destroy = function () {
                core.removeElement(this.spreadsheetTr);
                core.removeElement(this.timeAxisTr);
                _super.prototype.destroy.call(this);
            };
            Row.prototype.updateSize = function (isResize) {
                this.isSizeDirty = false;
            };
            return Row;
        }(core.Component));
    
        function updateExpanderIcon(el, isExpanded) {
            var classList = el.classList;
            if (isExpanded) {
                classList.remove('fc-icon-plus-square');
                classList.add('fc-icon-minus-square');
            }
            else {
                classList.remove('fc-icon-minus-square');
                classList.add('fc-icon-plus-square');
            }
        }
        function clearExpanderIcon(el) {
            var classList = el.classList;
            classList.remove('fc-icon-minus-square');
            classList.remove('fc-icon-plus-square');
        }
        function updateTrResourceId(tr, resourceId) {
            tr.setAttribute('data-resource-id', resourceId);
        }
    
        var GroupRow = /** @class */ (function (_super) {
            __extends(GroupRow, _super);
            function GroupRow() {
                var _this = _super !== null && _super.apply(this, arguments) || this;
                _this._renderCells = core.memoizeRendering(_this.renderCells, _this.unrenderCells);
                _this._updateExpanderIcon = core.memoizeRendering(_this.updateExpanderIcon, null, [_this._renderCells]);
                _this.onExpanderClick = function (ev) {
                    var props = _this.props;
                    _this.calendar.dispatch({
                        type: 'SET_RESOURCE_ENTITY_EXPANDED',
                        id: props.id,
                        isExpanded: !props.isExpanded
                    });
                };
                return _this;
            }
            GroupRow.prototype.render = function (props) {
                this._renderCells(props.group, props.spreadsheetColCnt);
                this._updateExpanderIcon(props.isExpanded);
                this.isSizeDirty = true;
            };
            GroupRow.prototype.destroy = function () {
                _super.prototype.destroy.call(this);
                this._renderCells.unrender(); // should unrender everything else
            };
            GroupRow.prototype.renderCells = function (group, spreadsheetColCnt) {
                var spreadsheetContentEl = this.renderSpreadsheetContent(group);
                this.spreadsheetTr.appendChild(core.createElement('td', {
                    className: 'fc-divider',
                    colSpan: spreadsheetColCnt // span across all columns
                }, this.spreadsheetHeightEl = core.createElement('div', null, spreadsheetContentEl)) // needed by setTrInnerHeight
                );
                this.expanderIconEl = spreadsheetContentEl.querySelector('.fc-icon');
                this.expanderIconEl.parentElement.addEventListener('click', this.onExpanderClick);
                // insert a single cell, with a single empty <div>.
                // there will be no content
                this.timeAxisTr.appendChild(core.createElement('td', { className: 'fc-divider' }, this.timeAxisHeightEl = document.createElement('div')));
            };
            GroupRow.prototype.unrenderCells = function () {
                this.spreadsheetTr.innerHTML = '';
                this.timeAxisTr.innerHTML = '';
            };
            /*
            Renders the content wrapper element that will be inserted into this row's TD cell.
            */
            GroupRow.prototype.renderSpreadsheetContent = function (group) {
                var text = this.renderCellText(group);
                var contentEl = core.htmlToElement('<div class="fc-cell-content">' +
                    '<span class="fc-expander">' +
                    '<span class="fc-icon"></span>' +
                    '</span>' +
                    '<span class="fc-cell-text">' +
                    (text ? core.htmlEscape(text) : '&nbsp;') +
                    '</span>' +
                    '</div>');
                var filter = group.spec.render;
                if (typeof filter === 'function') {
                    contentEl = filter(contentEl, group.value) || contentEl;
                }
                return contentEl;
            };
            GroupRow.prototype.renderCellText = function (group) {
                var text = group.value || ''; // might be null/undefined if an ad-hoc grouping
                var filter = group.spec.text;
                if (typeof filter === 'function') {
                    text = filter(text) || text;
                }
                return text;
            };
            GroupRow.prototype.getHeightEls = function () {
                return [this.spreadsheetHeightEl, this.timeAxisHeightEl];
            };
            GroupRow.prototype.updateExpanderIcon = function (isExpanded) {
                updateExpanderIcon(this.expanderIconEl, isExpanded);
            };
            return GroupRow;
        }(Row));
        GroupRow.addEqualityFuncs({
            group: ResourceCommonPlugin.isGroupsEqual // HACK for ResourceTimelineView::renderRows
        });
    
        var SpreadsheetRow = /** @class */ (function (_super) {
            __extends(SpreadsheetRow, _super);
            function SpreadsheetRow(context, tr) {
                var _this = _super.call(this, context) || this;
                _this._renderRow = core.memoizeRendering(_this.renderRow, _this.unrenderRow);
                _this._updateTrResourceId = core.memoizeRendering(updateTrResourceId, null, [_this._renderRow]);
                _this._updateExpanderIcon = core.memoizeRendering(_this.updateExpanderIcon, null, [_this._renderRow]);
                _this.onExpanderClick = function (ev) {
                    var props = _this.props;
                    _this.calendar.dispatch({
                        type: 'SET_RESOURCE_ENTITY_EXPANDED',
                        id: props.id,
                        isExpanded: !props.isExpanded
                    });
                };
                _this.tr = tr;
                return _this;
            }
            SpreadsheetRow.prototype.render = function (props) {
                this._renderRow(props.resource, props.rowSpans, props.depth, props.colSpecs);
                this._updateTrResourceId(this.tr, props.resource.id); // TODO: only use public ID?
                this._updateExpanderIcon(props.hasChildren, props.isExpanded);
            };
            SpreadsheetRow.prototype.destroy = function () {
                _super.prototype.destroy.call(this);
                this._renderRow.unrender(); // should unrender everything else
            };
            SpreadsheetRow.prototype.renderRow = function (resource, rowSpans, depth, colSpecs) {
                var _a = this, tr = _a.tr, theme = _a.theme, calendar = _a.calendar, view = _a.view;
                var resourceFields = ResourceCommonPlugin.buildResourceFields(resource); // slightly inefficient. already done up the call stack
                var mainTd;
                for (var i = 0; i < colSpecs.length; i++) {
                    var colSpec = colSpecs[i];
                    var rowSpan = rowSpans[i];
                    if (rowSpan === 0) { // not responsible for group-based rows. VRowGroup is
                        continue;
                    }
                    else if (rowSpan == null) {
                        rowSpan = 1;
                    }
                    var text = void 0;
                    if (colSpec.field) {
                        text = resourceFields[colSpec.field];
                    }
                    else {
                        text = ResourceCommonPlugin.buildResourceTextFunc(colSpec.text, calendar)(resource);
                    }
                    var contentEl = core.htmlToElement('<div class="fc-cell-content">' +
                        (colSpec.isMain ? renderIconHtml(depth) : '') +
                        '<span class="fc-cell-text">' +
                        (text ? core.htmlEscape(text) : '&nbsp;') +
                        '</span>' +
                        '</div>');
                    if (typeof colSpec.render === 'function') { // a filter function for the element
                        contentEl = colSpec.render(new ResourceCommonPlugin.ResourceApi(calendar, resource), contentEl) || contentEl;
                    }
                    if (rowSpan > 1) {
                        contentEl.classList.add('fc-sticky');
                    }
                    var td = core.createElement('td', {
                        className: theme.getClass('widgetContent'),
                        rowspan: rowSpan
                    }, contentEl);
                    // the first cell of the row needs to have an inner div for setTrInnerHeight
                    if (colSpec.isMain) {
                        td.appendChild(this.heightEl = core.createElement('div', null, td.childNodes) // inner wrap
                        );
                        mainTd = td;
                    }
                    tr.appendChild(td);
                }
                this.expanderIconEl = tr.querySelector('.fc-expander-space .fc-icon');
                // wait until very end
                view.publiclyTrigger('resourceRender', [
                    {
                        resource: new ResourceCommonPlugin.ResourceApi(calendar, resource),
                        el: mainTd,
                        view: view
                    }
                ]);
            };
            SpreadsheetRow.prototype.unrenderRow = function () {
                this.tr.innerHTML = '';
            };
            SpreadsheetRow.prototype.updateExpanderIcon = function (hasChildren, isExpanded) {
                var expanderIconEl = this.expanderIconEl;
                var expanderEl = expanderIconEl.parentElement;
                if (expanderIconEl &&
                    expanderEl // why would this be null?? was the case in IE11
                ) {
                    if (hasChildren) {
                        expanderEl.addEventListener('click', this.onExpanderClick);
                        expanderEl.classList.add('fc-expander');
                        updateExpanderIcon(expanderIconEl, isExpanded);
                    }
                    else {
                        expanderEl.removeEventListener('click', this.onExpanderClick);
                        expanderEl.classList.remove('fc-expander');
                        clearExpanderIcon(expanderIconEl);
                    }
                }
            };
            return SpreadsheetRow;
        }(core.Component));
        /*
        Renders the HTML responsible for the subrow expander area,
        as well as the space before it (used to align expanders of similar depths)
        */
        function renderIconHtml(depth) {
            var html = '';
            for (var i = 0; i < depth; i++) {
                html += '<span class="fc-icon"></span>';
            }
            html +=
                '<span class="fc-expander-space">' +
                    '<span class="fc-icon"></span>' +
                    '</span>';
            return html;
        }
    
        var ResourceRow = /** @class */ (function (_super) {
            __extends(ResourceRow, _super);
            function ResourceRow(context, a, b, c, d, timeAxis) {
                var _this = _super.call(this, context, a, b, c, d) || this;
                _this._updateTrResourceId = core.memoizeRendering(updateTrResourceId);
                _this.spreadsheetRow = new SpreadsheetRow(context, _this.spreadsheetTr);
                _this.timeAxisTr.appendChild(core.createElement('td', { className: _this.theme.getClass('widgetContent') }, _this.innerContainerEl = document.createElement('div')));
                _this.lane = new TimelinePlugin.TimelineLane(context, _this.innerContainerEl, _this.innerContainerEl, timeAxis);
                return _this;
            }
            ResourceRow.prototype.destroy = function () {
                this.spreadsheetRow.destroy();
                this.lane.destroy();
                _super.prototype.destroy.call(this);
            };
            ResourceRow.prototype.render = function (props) {
                // spreadsheetRow handles calling updateTrResourceId for spreadsheetTr
                this.spreadsheetRow.receiveProps({
                    colSpecs: props.colSpecs,
                    id: props.id,
                    rowSpans: props.rowSpans,
                    depth: props.depth,
                    isExpanded: props.isExpanded,
                    hasChildren: props.hasChildren,
                    resource: props.resource
                });
                this._updateTrResourceId(this.timeAxisTr, props.resource.id);
                this.lane.receiveProps({
                    dateProfile: props.dateProfile,
                    nextDayThreshold: props.nextDayThreshold,
                    businessHours: props.businessHours,
                    eventStore: props.eventStore,
                    eventUiBases: props.eventUiBases,
                    dateSelection: props.dateSelection,
                    eventSelection: props.eventSelection,
                    eventDrag: props.eventDrag,
                    eventResize: props.eventResize
                });
                this.isSizeDirty = true;
            };
            ResourceRow.prototype.updateSize = function (isResize) {
                _super.prototype.updateSize.call(this, isResize);
                this.lane.updateSize(isResize);
            };
            ResourceRow.prototype.getHeightEls = function () {
                return [this.spreadsheetRow.heightEl, this.innerContainerEl];
            };
            return ResourceRow;
        }(Row));
        ResourceRow.addEqualityFuncs({
            rowSpans: core.isArraysEqual // HACK for isSizeDirty, ResourceTimelineView::renderRows
        });
    
        var COL_MIN_WIDTH = 30;
        var SpreadsheetHeader = /** @class */ (function (_super) {
            __extends(SpreadsheetHeader, _super);
            function SpreadsheetHeader(context, parentEl) {
                var _this = _super.call(this, context) || this;
                _this.resizables = [];
                _this.colWidths = [];
                _this.emitter = new core.EmitterMixin();
                parentEl.appendChild(_this.tableEl = core.createElement('table', {
                    className: _this.theme.getClass('tableGrid')
                }));
                return _this;
            }
            SpreadsheetHeader.prototype.destroy = function () {
                for (var _i = 0, _a = this.resizables; _i < _a.length; _i++) {
                    var resizable = _a[_i];
                    resizable.destroy();
                }
                core.removeElement(this.tableEl);
                _super.prototype.destroy.call(this);
            };
            SpreadsheetHeader.prototype.render = function (props) {
                var theme = this.theme;
                var colSpecs = props.colSpecs;
                var html = '<colgroup>' + props.colTags + '</colgroup>' +
                    '<tbody>';
                if (props.superHeaderText) {
                    html +=
                        '<tr class="fc-super">' +
                            '<th class="' + theme.getClass('widgetHeader') + '" colspan="' + colSpecs.length + '">' +
                            '<div class="fc-cell-content">' +
                            '<span class="fc-cell-text">' +
                            core.htmlEscape(props.superHeaderText) +
                            '</span>' +
                            '</div>' +
                            '</th>' +
                            '</tr>';
                }
                html += '<tr>';
                for (var i = 0; i < colSpecs.length; i++) {
                    var o = colSpecs[i];
                    var isLast = i === (colSpecs.length - 1);
                    html +=
                        "<th class=\"" + theme.getClass('widgetHeader') + "\">" +
                            '<div>' +
                            '<div class="fc-cell-content">' +
                            (o.isMain ?
                                '<span class="fc-expander-space">' +
                                    '<span class="fc-icon"></span>' +
                                    '</span>' :
                                '') +
                            '<span class="fc-cell-text">' +
                            core.htmlEscape(o.labelText || '') + // what about normalizing this value ahead of time?
                            '</span>' +
                            '</div>' +
                            (!isLast ? '<div class="fc-col-resizer"></div>' : '') +
                            '</div>' +
                            '</th>';
                }
                html += '</tr>';
                html += '</tbody>';
                this.tableEl.innerHTML = html;
                this.thEls = Array.prototype.slice.call(this.tableEl.querySelectorAll('th'));
                this.colEls = Array.prototype.slice.call(this.tableEl.querySelectorAll('col'));
                this.resizerEls = Array.prototype.slice.call(this.tableEl.querySelectorAll('.fc-col-resizer'));
                this.initColResizing();
            };
            SpreadsheetHeader.prototype.initColResizing = function () {
                var _this = this;
                var ElementDraggingImpl = this.calendar.pluginSystem.hooks.elementDraggingImpl;
                if (ElementDraggingImpl) {
                    this.resizables = this.resizerEls.map(function (handleEl, colIndex) {
                        var dragging = new ElementDraggingImpl(handleEl);
                        var startWidth;
                        dragging.emitter.on('dragstart', function () {
                            startWidth = _this.colWidths[colIndex];
                            if (typeof startWidth !== 'number') {
                                startWidth = _this.thEls[colIndex].getBoundingClientRect().width;
                            }
                        });
                        dragging.emitter.on('dragmove', function (pev) {
                            _this.colWidths[colIndex] = Math.max(startWidth + pev.deltaX * (_this.isRtl ? -1 : 1), COL_MIN_WIDTH);
                            _this.emitter.trigger('colwidthchange', _this.colWidths);
                        });
                        dragging.setAutoScrollEnabled(false); // because gets weird with auto-scrolling time area
                        return dragging;
                    });
                }
            };
            return SpreadsheetHeader;
        }(core.Component));
    
        var Spreadsheet = /** @class */ (function (_super) {
            __extends(Spreadsheet, _super);
            function Spreadsheet(context, headParentEl, bodyParentEl) {
                var _this = _super.call(this, context) || this;
                _this._renderCells = core.memoizeRendering(_this.renderCells, _this.unrenderCells);
                _this.layout = new TimelinePlugin.HeaderBodyLayout(headParentEl, bodyParentEl, 'clipped-scroll');
                var headerEnhancedScroller = _this.layout.headerScroller.enhancedScroll;
                var bodyEnhancedScroller = _this.layout.bodyScroller.enhancedScroll;
                _this.header = new SpreadsheetHeader(context, headerEnhancedScroller.canvas.contentEl);
                _this.header.emitter.on('colwidthchange', function (colWidths) {
                    _this.applyColWidths(colWidths);
                });
                bodyEnhancedScroller.canvas.contentEl
                    .appendChild(_this.bodyContainerEl = core.createElement('div', { className: 'fc-rows' }, '<table>' +
                    '<colgroup />' +
                    '<tbody />' +
                    '</table>'));
                _this.bodyColGroup = _this.bodyContainerEl.querySelector('colgroup');
                _this.bodyTbody = _this.bodyContainerEl.querySelector('tbody');
                return _this;
            }
            Spreadsheet.prototype.destroy = function () {
                this.header.destroy();
                this.layout.destroy();
                this._renderCells.unrender();
                _super.prototype.destroy.call(this);
            };
            Spreadsheet.prototype.render = function (props) {
                this._renderCells(props.superHeaderText, props.colSpecs);
            };
            Spreadsheet.prototype.renderCells = function (superHeaderText, colSpecs) {
                var colTags = this.renderColTags(colSpecs);
                this.header.receiveProps({
                    superHeaderText: superHeaderText,
                    colSpecs: colSpecs,
                    colTags: colTags
                });
                this.bodyColGroup.innerHTML = colTags;
                this.bodyColEls = Array.prototype.slice.call(this.bodyColGroup.querySelectorAll('col'));
                this.applyColWidths(colSpecs.map(function (colSpec) { return colSpec.width; }));
            };
            Spreadsheet.prototype.unrenderCells = function () {
                this.bodyColGroup.innerHTML = '';
            };
            Spreadsheet.prototype.renderColTags = function (colSpecs) {
                var html = '';
                for (var _i = 0, colSpecs_1 = colSpecs; _i < colSpecs_1.length; _i++) {
                    var o = colSpecs_1[_i];
                    if (o.isMain) {
                        html += '<col class="fc-main-col"/>';
                    }
                    else {
                        html += '<col/>';
                    }
                }
                return html;
            };
            Spreadsheet.prototype.updateSize = function (isResize, totalHeight, isAuto) {
                this.layout.setHeight(totalHeight, isAuto);
            };
            Spreadsheet.prototype.applyColWidths = function (colWidths) {
                var _this = this;
                colWidths.forEach(function (colWidth, colIndex) {
                    var headEl = _this.header.colEls[colIndex]; // bad to access child
                    var bodyEl = _this.bodyColEls[colIndex];
                    var styleVal;
                    if (typeof colWidth === 'number') {
                        styleVal = colWidth + 'px';
                    }
                    else if (typeof colWidth == null) {
                        styleVal = '';
                    }
                    headEl.style.width = bodyEl.style.width = styleVal;
                });
            };
            return Spreadsheet;
        }(core.Component));
    
        var MIN_RESOURCE_AREA_WIDTH = 30; // definitely bigger than scrollbars
        var ResourceTimelineView = /** @class */ (function (_super) {
            __extends(ResourceTimelineView, _super);
            function ResourceTimelineView(context, viewSpec, dateProfileGenerator, parentEl) {
                var _this = _super.call(this, context, viewSpec, dateProfileGenerator, parentEl) || this;
                _this.isStickyScrollDirty = false;
                _this.rowNodes = [];
                _this.rowComponents = [];
                _this.rowComponentsById = {};
                _this.resourceAreaWidthDraggings = [];
                _this.splitter = new ResourceCommonPlugin.ResourceSplitter(); // doesn't let it do businessHours tho
                _this.hasResourceBusinessHours = core.memoize(hasResourceBusinessHours);
                _this.buildRowNodes = core.memoize(ResourceCommonPlugin.buildRowNodes);
                _this.hasNesting = core.memoize(hasNesting);
                _this._updateHasNesting = core.memoizeRendering(_this.updateHasNesting);
                var allColSpecs = _this.opt('resourceColumns') || [];
                var labelText = _this.opt('resourceLabelText'); // TODO: view.override
                var defaultLabelText = 'Resources'; // TODO: view.defaults
                var superHeaderText = null;
                if (!allColSpecs.length) {
                    allColSpecs.push({
                        labelText: labelText || defaultLabelText,
                        text: ResourceCommonPlugin.buildResourceTextFunc(_this.opt('resourceText'), _this.calendar)
                    });
                }
                else {
                    superHeaderText = labelText;
                }
                var plainColSpecs = [];
                var groupColSpecs = [];
                var groupSpecs = [];
                var isVGrouping = false;
                var isHGrouping = false;
                for (var _i = 0, allColSpecs_1 = allColSpecs; _i < allColSpecs_1.length; _i++) {
                    var colSpec = allColSpecs_1[_i];
                    if (colSpec.group) {
                        groupColSpecs.push(colSpec);
                    }
                    else {
                        plainColSpecs.push(colSpec);
                    }
                }
                plainColSpecs[0].isMain = true;
                if (groupColSpecs.length) {
                    groupSpecs = groupColSpecs;
                    isVGrouping = true;
                }
                else {
                    var hGroupField = _this.opt('resourceGroupField');
                    if (hGroupField) {
                        isHGrouping = true;
                        groupSpecs.push({
                            field: hGroupField,
                            text: _this.opt('resourceGroupText'),
                            render: _this.opt('resourceGroupRender')
                        });
                    }
                }
                var allOrderSpecs = core.parseFieldSpecs(_this.opt('resourceOrder'));
                var plainOrderSpecs = [];
                for (var _a = 0, allOrderSpecs_1 = allOrderSpecs; _a < allOrderSpecs_1.length; _a++) {
                    var orderSpec = allOrderSpecs_1[_a];
                    var isGroup = false;
                    for (var _b = 0, groupSpecs_1 = groupSpecs; _b < groupSpecs_1.length; _b++) {
                        var groupSpec = groupSpecs_1[_b];
                        if (groupSpec.field === orderSpec.field) {
                            groupSpec.order = orderSpec.order; // -1, 0, 1
                            isGroup = true;
                            break;
                        }
                    }
                    if (!isGroup) {
                        plainOrderSpecs.push(orderSpec);
                    }
                }
                _this.superHeaderText = superHeaderText;
                _this.isVGrouping = isVGrouping;
                _this.isHGrouping = isHGrouping;
                _this.groupSpecs = groupSpecs;
                _this.colSpecs = groupColSpecs.concat(plainColSpecs);
                _this.orderSpecs = plainOrderSpecs;
                // START RENDERING...
                _this.el.classList.add('fc-timeline');
                if (_this.opt('eventOverlap') === false) {
                    _this.el.classList.add('fc-no-overlap');
                }
                _this.el.innerHTML = _this.renderSkeletonHtml();
                _this.resourceAreaHeadEl = _this.el.querySelector('thead .fc-resource-area');
                _this.setResourceAreaWidth(_this.opt('resourceAreaWidth'));
                _this.initResourceAreaWidthDragging();
                _this.miscHeight = _this.el.getBoundingClientRect().height;
                _this.spreadsheet = new Spreadsheet(_this.context, _this.resourceAreaHeadEl, _this.el.querySelector('tbody .fc-resource-area'));
                _this.timeAxis = new TimelinePlugin.TimeAxis(_this.context, _this.el.querySelector('thead .fc-time-area'), _this.el.querySelector('tbody .fc-time-area'));
                var timeAxisRowContainer = core.createElement('div', { className: 'fc-rows' }, '<table><tbody /></table>');
                _this.timeAxis.layout.bodyScroller.enhancedScroll.canvas.contentEl.appendChild(timeAxisRowContainer);
                _this.timeAxisTbody = timeAxisRowContainer.querySelector('tbody');
                _this.lane = new TimelinePlugin.TimelineLane(_this.context, null, _this.timeAxis.layout.bodyScroller.enhancedScroll.canvas.bgEl, _this.timeAxis);
                _this.bodyScrollJoiner = new TimelinePlugin.ScrollJoiner('vertical', [
                    _this.spreadsheet.layout.bodyScroller,
                    _this.timeAxis.layout.bodyScroller
                ]);
                // after scrolljoiner
                _this.spreadsheetBodyStickyScroller = new TimelinePlugin.StickyScroller(_this.spreadsheet.layout.bodyScroller.enhancedScroll, _this.isRtl, true // isVertical
                );
                _this.spreadsheet.receiveProps({
                    superHeaderText: _this.superHeaderText,
                    colSpecs: _this.colSpecs
                });
                // Component...
                context.calendar.registerInteractiveComponent(_this, {
                    el: _this.timeAxis.slats.el
                });
                return _this;
            }
            ResourceTimelineView.prototype.renderSkeletonHtml = function () {
                var theme = this.theme;
                return "<table class=\"" + theme.getClass('tableGrid') + "\"> <thead class=\"fc-head\"> <tr> <td class=\"fc-resource-area " + theme.getClass('widgetHeader') + "\"></td> <td class=\"fc-divider fc-col-resizer " + theme.getClass('widgetHeader') + "\"></td> <td class=\"fc-time-area " + theme.getClass('widgetHeader') + "\"></td> </tr> </thead> <tbody class=\"fc-body\"> <tr> <td class=\"fc-resource-area " + theme.getClass('widgetContent') + "\"></td> <td class=\"fc-divider fc-col-resizer " + theme.getClass('widgetHeader') + "\"></td> <td class=\"fc-time-area " + theme.getClass('widgetContent') + "\"></td> </tr> </tbody> </table>";
            };
            ResourceTimelineView.prototype.render = function (props) {
                _super.prototype.render.call(this, props);
                var splitProps = this.splitter.splitProps(props);
                var hasResourceBusinessHours = this.hasResourceBusinessHours(props.resourceStore);
                this.timeAxis.receiveProps({
                    dateProfile: props.dateProfile
                });
                // for all-resource bg events / selections / business-hours
                this.lane.receiveProps(__assign({}, splitProps[''], { dateProfile: props.dateProfile, nextDayThreshold: this.nextDayThreshold, businessHours: hasResourceBusinessHours ? null : props.businessHours }));
                var newRowNodes = this.buildRowNodes(props.resourceStore, this.groupSpecs, this.orderSpecs, this.isVGrouping, props.resourceEntityExpansions, this.opt('resourcesInitiallyExpanded'));
                this._updateHasNesting(this.hasNesting(newRowNodes));
                this.diffRows(newRowNodes);
                this.renderRows(props.dateProfile, hasResourceBusinessHours ? props.businessHours : null, // CONFUSING, comment
                splitProps);
            };
            ResourceTimelineView.prototype.updateHasNesting = function (isNesting) {
                var classList = this.el.classList;
                if (isNesting) {
                    classList.remove('fc-flat');
                }
                else {
                    classList.add('fc-flat');
                }
            };
            ResourceTimelineView.prototype.diffRows = function (newNodes) {
                var oldNodes = this.rowNodes;
                var oldLen = oldNodes.length;
                var oldIndexHash = {}; // id -> index
                var oldI = 0;
                var newI = 0;
                for (oldI = 0; oldI < oldLen; oldI++) {
                    oldIndexHash[oldNodes[oldI].id] = oldI;
                }
                // iterate new nodes
                for (oldI = 0, newI = 0; newI < newNodes.length; newI++) {
                    var newNode = newNodes[newI];
                    var oldIFound = oldIndexHash[newNode.id];
                    if (oldIFound != null && oldIFound >= oldI) {
                        this.removeRows(newI, oldIFound - oldI, oldNodes); // won't do anything if same index
                        oldI = oldIFound + 1;
                    }
                    else {
                        this.addRow(newI, newNode);
                    }
                }
                // old rows that weren't found need to be removed
                this.removeRows(newI, oldLen - oldI, oldNodes); // won't do anything if same index
                this.rowNodes = newNodes;
            };
            /*
            rowComponents is the in-progress result
            */
            ResourceTimelineView.prototype.addRow = function (index, rowNode) {
                var _a = this, rowComponents = _a.rowComponents, rowComponentsById = _a.rowComponentsById;
                var nextComponent = rowComponents[index];
                var newComponent = this.buildChildComponent(rowNode, this.spreadsheet.bodyTbody, nextComponent ? nextComponent.spreadsheetTr : null, this.timeAxisTbody, nextComponent ? nextComponent.timeAxisTr : null);
                rowComponents.splice(index, 0, newComponent);
                rowComponentsById[rowNode.id] = newComponent;
            };
            ResourceTimelineView.prototype.removeRows = function (startIndex, len, oldRowNodes) {
                if (len) {
                    var _a = this, rowComponents = _a.rowComponents, rowComponentsById = _a.rowComponentsById;
                    for (var i = 0; i < len; i++) {
                        var rowComponent = rowComponents[startIndex + i];
                        rowComponent.destroy();
                        delete rowComponentsById[oldRowNodes[i].id];
                    }
                    rowComponents.splice(startIndex, len);
                }
            };
            ResourceTimelineView.prototype.buildChildComponent = function (node, spreadsheetTbody, spreadsheetNext, timeAxisTbody, timeAxisNext) {
                if (node.group) {
                    return new GroupRow(this.context, spreadsheetTbody, spreadsheetNext, timeAxisTbody, timeAxisNext);
                }
                else if (node.resource) {
                    return new ResourceRow(this.context, spreadsheetTbody, spreadsheetNext, timeAxisTbody, timeAxisNext, this.timeAxis);
                }
            };
            ResourceTimelineView.prototype.renderRows = function (dateProfile, fallbackBusinessHours, splitProps) {
                var _a = this, rowNodes = _a.rowNodes, rowComponents = _a.rowComponents;
                for (var i = 0; i < rowNodes.length; i++) {
                    var rowNode = rowNodes[i];
                    var rowComponent = rowComponents[i];
                    if (rowNode.group) {
                        rowComponent.receiveProps({
                            spreadsheetColCnt: this.colSpecs.length,
                            id: rowNode.id,
                            isExpanded: rowNode.isExpanded,
                            group: rowNode.group
                        });
                    }
                    else {
                        var resource = rowNode.resource;
                        rowComponent.receiveProps(__assign({}, splitProps[resource.id], { dateProfile: dateProfile, nextDayThreshold: this.nextDayThreshold, businessHours: resource.businessHours || fallbackBusinessHours, colSpecs: this.colSpecs, id: rowNode.id, rowSpans: rowNode.rowSpans, depth: rowNode.depth, isExpanded: rowNode.isExpanded, hasChildren: rowNode.hasChildren, resource: rowNode.resource }));
                    }
                }
            };
            ResourceTimelineView.prototype.updateSize = function (isResize, viewHeight, isAuto) {
                // FYI: this ordering is really important
                var calendar = this.calendar;
                var isBaseSizing = isResize || calendar.isViewUpdated || calendar.isDatesUpdated || calendar.isEventsUpdated;
                if (isBaseSizing) {
                    this.syncHeadHeights();
                    this.timeAxis.updateSize(isResize, viewHeight - this.miscHeight, isAuto);
                    this.spreadsheet.updateSize(isResize, viewHeight - this.miscHeight, isAuto);
                }
                var rowSizingCnt = this.updateRowSizes(isResize);
                this.lane.updateSize(isResize); // is efficient. uses flags
                if (isBaseSizing || rowSizingCnt) {
                    this.bodyScrollJoiner.update();
                    this.timeAxis.layout.scrollJoiner.update(); // hack
                    this.rowPositions = new core.PositionCache(this.timeAxis.slats.el, this.rowComponents.map(function (rowComponent) {
                        return rowComponent.timeAxisTr;
                    }), false, // isHorizontal
                    true // isVertical
                    );
                    this.rowPositions.build();
                    this.isStickyScrollDirty = true;
                }
            };
            ResourceTimelineView.prototype.syncHeadHeights = function () {
                var spreadsheetHeadEl = this.spreadsheet.header.tableEl;
                var timeAxisHeadEl = this.timeAxis.header.tableEl;
                spreadsheetHeadEl.style.height = '';
                timeAxisHeadEl.style.height = '';
                var max = Math.max(spreadsheetHeadEl.getBoundingClientRect().height, timeAxisHeadEl.getBoundingClientRect().height);
                spreadsheetHeadEl.style.height =
                    timeAxisHeadEl.style.height = max + 'px';
            };
            ResourceTimelineView.prototype.updateRowSizes = function (isResize) {
                var dirtyRowComponents = this.rowComponents;
                if (!isResize) {
                    dirtyRowComponents = dirtyRowComponents.filter(function (rowComponent) {
                        return rowComponent.isSizeDirty;
                    });
                }
                var elArrays = dirtyRowComponents.map(function (rowComponent) {
                    return rowComponent.getHeightEls();
                });
                // reset to natural heights
                for (var _i = 0, elArrays_1 = elArrays; _i < elArrays_1.length; _i++) {
                    var elArray = elArrays_1[_i];
                    for (var _a = 0, elArray_1 = elArray; _a < elArray_1.length; _a++) {
                        var el = elArray_1[_a];
                        el.style.height = '';
                    }
                }
                // let rows update their contents' heights
                for (var _b = 0, dirtyRowComponents_1 = dirtyRowComponents; _b < dirtyRowComponents_1.length; _b++) {
                    var rowComponent = dirtyRowComponents_1[_b];
                    rowComponent.updateSize(isResize); // will reset isSizeDirty
                }
                var maxHeights = elArrays.map(function (elArray) {
                    var maxHeight = null;
                    for (var _i = 0, elArray_2 = elArray; _i < elArray_2.length; _i++) {
                        var el = elArray_2[_i];
                        var height = el.getBoundingClientRect().height;
                        if (maxHeight === null || height > maxHeight) {
                            maxHeight = height;
                        }
                    }
                    return maxHeight;
                });
                for (var i = 0; i < elArrays.length; i++) {
                    for (var _c = 0, _d = elArrays[i]; _c < _d.length; _c++) {
                        var el = _d[_c];
                        el.style.height = maxHeights[i] + 'px';
                    }
                }
                return dirtyRowComponents.length;
            };
            ResourceTimelineView.prototype.destroy = function () {
                for (var _i = 0, _a = this.rowComponents; _i < _a.length; _i++) {
                    var rowComponent = _a[_i];
                    rowComponent.destroy();
                }
                this.rowNodes = [];
                this.rowComponents = [];
                this.spreadsheet.destroy();
                this.timeAxis.destroy();
                for (var _b = 0, _c = this.resourceAreaWidthDraggings; _b < _c.length; _b++) {
                    var resourceAreaWidthDragging = _c[_b];
                    resourceAreaWidthDragging.destroy();
                }
                this.spreadsheetBodyStickyScroller.destroy();
                _super.prototype.destroy.call(this);
                this.calendar.unregisterInteractiveComponent(this);
            };
            // Now Indicator
            // ------------------------------------------------------------------------------------------
            ResourceTimelineView.prototype.getNowIndicatorUnit = function (dateProfile) {
                return this.timeAxis.getNowIndicatorUnit(dateProfile);
            };
            ResourceTimelineView.prototype.renderNowIndicator = function (date) {
                this.timeAxis.renderNowIndicator(date);
            };
            ResourceTimelineView.prototype.unrenderNowIndicator = function () {
                this.timeAxis.unrenderNowIndicator();
            };
            // Scrolling
            // ------------------------------------------------------------------------------------------------------------------
            // this is useful for scrolling prev/next dates while resource is scrolled down
            ResourceTimelineView.prototype.queryScroll = function () {
                var scroll = _super.prototype.queryScroll.call(this);
                if (this.props.resourceStore) {
                    __assign(scroll, this.queryResourceScroll());
                }
                return scroll;
            };
            ResourceTimelineView.prototype.applyScroll = function (scroll, isResize) {
                _super.prototype.applyScroll.call(this, scroll, isResize);
                if (this.props.resourceStore) {
                    this.applyResourceScroll(scroll);
                }
                // avoid updating stickyscroll too often
                if (isResize || this.isStickyScrollDirty) {
                    this.isStickyScrollDirty = false;
                    this.spreadsheetBodyStickyScroller.updateSize();
                    this.timeAxis.updateStickyScrollers();
                }
            };
            ResourceTimelineView.prototype.computeDateScroll = function (duration) {
                return this.timeAxis.computeDateScroll(duration);
            };
            ResourceTimelineView.prototype.queryDateScroll = function () {
                return this.timeAxis.queryDateScroll();
            };
            ResourceTimelineView.prototype.applyDateScroll = function (scroll) {
                this.timeAxis.applyDateScroll(scroll);
            };
            ResourceTimelineView.prototype.queryResourceScroll = function () {
                var _a = this, rowComponents = _a.rowComponents, rowNodes = _a.rowNodes;
                var scroll = {};
                var scrollerTop = this.timeAxis.layout.bodyScroller.el.getBoundingClientRect().top; // fixed position
                for (var i = 0; i < rowComponents.length; i++) {
                    var rowComponent = rowComponents[i];
                    var rowNode = rowNodes[i];
                    var el = rowComponent.timeAxisTr;
                    var elBottom = el.getBoundingClientRect().bottom; // fixed position
                    if (elBottom > scrollerTop) {
                        scroll.rowId = rowNode.id;
                        scroll.bottom = elBottom - scrollerTop;
                        break;
                    }
                }
                // TODO: what about left scroll state for spreadsheet area?
                return scroll;
            };
            ResourceTimelineView.prototype.applyResourceScroll = function (scroll) {
                var rowId = scroll.forcedRowId || scroll.rowId;
                if (rowId) {
                    var rowComponent = this.rowComponentsById[rowId];
                    if (rowComponent) {
                        var el = rowComponent.timeAxisTr;
                        if (el) {
                            var innerTop = this.timeAxis.layout.bodyScroller.enhancedScroll.canvas.el.getBoundingClientRect().top;
                            var rowRect = el.getBoundingClientRect();
                            var scrollTop = (scroll.forcedRowId ?
                                rowRect.top : // just use top edge
                                rowRect.bottom - scroll.bottom) - // pixels from bottom edge
                                innerTop;
                            this.timeAxis.layout.bodyScroller.enhancedScroll.setScrollTop(scrollTop);
                            this.spreadsheet.layout.bodyScroller.enhancedScroll.setScrollTop(scrollTop);
                        }
                    }
                }
            };
            // TODO: scrollToResource
            // Hit System
            // ------------------------------------------------------------------------------------------
            ResourceTimelineView.prototype.buildPositionCaches = function () {
                this.timeAxis.slats.updateSize();
                this.rowPositions.build();
            };
            ResourceTimelineView.prototype.queryHit = function (positionLeft, positionTop) {
                var rowPositions = this.rowPositions;
                var slats = this.timeAxis.slats;
                var rowIndex = rowPositions.topToIndex(positionTop);
                if (rowIndex != null) {
                    var resource = this.rowNodes[rowIndex].resource;
                    if (resource) { // not a group
                        var slatHit = slats.positionToHit(positionLeft);
                        if (slatHit) {
                            return {
                                component: this,
                                dateSpan: {
                                    range: slatHit.dateSpan.range,
                                    allDay: slatHit.dateSpan.allDay,
                                    resourceId: resource.id
                                },
                                rect: {
                                    left: slatHit.left,
                                    right: slatHit.right,
                                    top: rowPositions.tops[rowIndex],
                                    bottom: rowPositions.bottoms[rowIndex]
                                },
                                dayEl: slatHit.dayEl,
                                layer: 0
                            };
                        }
                    }
                }
            };
            // Resource Area
            // ------------------------------------------------------------------------------------------------------------------
            ResourceTimelineView.prototype.setResourceAreaWidth = function (widthVal) {
                this.resourceAreaWidth = widthVal;
                core.applyStyleProp(this.resourceAreaHeadEl, 'width', widthVal || '');
            };
            ResourceTimelineView.prototype.initResourceAreaWidthDragging = function () {
                var _this = this;
                var resourceAreaDividerEls = Array.prototype.slice.call(this.el.querySelectorAll('.fc-col-resizer'));
                var ElementDraggingImpl = this.calendar.pluginSystem.hooks.elementDraggingImpl;
                if (ElementDraggingImpl) {
                    this.resourceAreaWidthDraggings = resourceAreaDividerEls.map(function (el) {
                        var dragging = new ElementDraggingImpl(el);
                        var dragStartWidth;
                        var viewWidth;
                        dragging.emitter.on('dragstart', function () {
                            dragStartWidth = _this.resourceAreaWidth;
                            if (typeof dragStartWidth !== 'number') {
                                dragStartWidth = _this.resourceAreaHeadEl.getBoundingClientRect().width;
                            }
                            viewWidth = _this.el.getBoundingClientRect().width;
                        });
                        dragging.emitter.on('dragmove', function (pev) {
                            var newWidth = dragStartWidth + pev.deltaX * (_this.isRtl ? -1 : 1);
                            newWidth = Math.max(newWidth, MIN_RESOURCE_AREA_WIDTH);
                            newWidth = Math.min(newWidth, viewWidth - MIN_RESOURCE_AREA_WIDTH);
                            _this.setResourceAreaWidth(newWidth);
                        });
                        dragging.setAutoScrollEnabled(false); // because gets weird with auto-scrolling time area
                        return dragging;
                    });
                }
            };
            ResourceTimelineView.needsResourceData = true; // for ResourceViewProps
            return ResourceTimelineView;
        }(core.View));
        function hasResourceBusinessHours(resourceStore) {
            for (var resourceId in resourceStore) {
                var resource = resourceStore[resourceId];
                if (resource.businessHours) {
                    return true;
                }
            }
            return false;
        }
        function hasNesting(nodes) {
            for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) {
                var node = nodes_1[_i];
                if (node.group) {
                    return true;
                }
                else if (node.resource) {
                    if (node.hasChildren) {
                        return true;
                    }
                }
            }
            return false;
        }
    
        var main = core.createPlugin({
            deps: [ResourceCommonPlugin__default, TimelinePlugin__default],
            defaultView: 'resourceTimelineDay',
            views: {
                resourceTimeline: {
                    class: ResourceTimelineView,
                    resourceAreaWidth: '30%',
                    resourcesInitiallyExpanded: true,
                    eventResizableFromStart: true // TODO: not DRY with this same setting in the main timeline config
                },
                resourceTimelineDay: {
                    type: 'resourceTimeline',
                    duration: { days: 1 }
                },
                resourceTimelineWeek: {
                    type: 'resourceTimeline',
                    duration: { weeks: 1 }
                },
                resourceTimelineMonth: {
                    type: 'resourceTimeline',
                    duration: { months: 1 }
                },
                resourceTimelineYear: {
                    type: 'resourceTimeline',
                    duration: { years: 1 }
                }
            }
        });
    
        exports.ResourceTimelineView = ResourceTimelineView;
        exports.default = main;
    
        Object.defineProperty(exports, '__esModule', { value: true });
    
    }));