UNPKG

@nova-ui/dashboards

Version:

Nova Dashboards is a framework designed to provide feature developers with a common solution for presenting data coming from various sources within a single view, as well as a set of predefined widget visualizations that are 100% configuration-driven and

253 lines 11.1 kB
"use strict"; // © 2022 SolarWinds Worldwide, LLC. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. Object.defineProperty(exports, "__esModule", { value: true }); exports.DashboardComponent = void 0; const tslib_1 = require("tslib"); const core_1 = require("@angular/core"); const angular_gridster2_1 = require("angular-gridster2"); const defaultsDeep_1 = tslib_1.__importDefault(require("lodash/defaultsDeep")); const bits_1 = require("@nova-ui/bits"); const default_gridster_config_1 = require("./default-gridster-config"); const types_1 = require("../../services/types"); const types_2 = require("../../types"); let DashboardComponent = class DashboardComponent { get dashboard() { return this.dashboardBuffer || this._dashboard; } set dashboard(value) { this._dashboard = value; this.dashboardBuffer = null; } get hostClass() { return true; } constructor(eventBus) { this.eventBus = eventBus; this.editMode = false; this.gridsterConfigChange = new core_1.EventEmitter(); this.dashboardChange = new core_1.EventEmitter(); this.gridsterItemsVisibilityMap = {}; this.orderWidgets = (a, b) => { const nextWidget = this.dashboard.positions[a.key]; const currentWidget = this.dashboard.positions[b.key]; return nextWidget.y - currentWidget.y || nextWidget.x - currentWidget.x; }; this.trackByFn = (index, item) => item.key; this.updateWidgetPosition = (item, itemComponent) => { const widgetId = String(itemComponent.widgetId); const dashboard = (0, bits_1.immutableSet)(this.dashboard, "positions." + widgetId, item); this.dashboardChange.emit(dashboard); this.eventBus.getStream(types_1.WIDGET_POSITION_CHANGE).next({ widgetId, payload: item, }); }; this.emitWidgetResize = (item, itemComponent) => { const widgetId = itemComponent.widgetId; this.eventBus.getStream(types_1.WIDGET_RESIZE).next({ widgetId, payload: { widgetId, height: itemComponent.height, width: itemComponent.width, }, }); }; } ngAfterViewInit() { // need to wait till DOM is rendered because of "getBoundingClientRect" under the hood setTimeout(() => this.calculateWidgetsVisibility()); } onGridsterScroll() { this.calculateWidgetsVisibility(); } ngOnChanges(changes) { if (changes.gridsterConfig) { if (changes.gridsterConfig.isFirstChange()) { const gridsterConfig = (0, defaultsDeep_1.default)(this.gridsterConfig || {}, default_gridster_config_1.DEFAULT_GRIDSTER_CONFIG); this.hookEvent(gridsterConfig, "itemChangeCallback", this.updateWidgetPosition); this.hookEvent(gridsterConfig, "itemResizeCallback", this.emitWidgetResize); this.gridsterConfigChange.emit(gridsterConfig); } if (this.gridsterConfig?.api) { this.gridsterConfig.api.optionsChanged?.(); } } if (changes.editMode) { if (!this.gridsterConfig.resizable) { throw new Error(`Gridster's resizable prop is undefined`); } this.gridsterConfig.resizable.enabled = this.editMode; if (!this.gridsterConfig.draggable) { throw new Error(`Gridster's draggable prop is undefined`); } this.gridsterConfig.draggable.enabled = this.editMode; this.gridsterConfigChange.emit(Object.assign({}, this.gridsterConfig)); this.eventBus .getStream(types_1.DASHBOARD_EDIT_MODE) .next({ payload: this.editMode }); } // TODO: position doesn't update on external change of position // if (!changes.dashboard.isFirstChange() && // changes.dashboard.currentValue.positions !== changes.dashboard.previousValue.positions) { // if (this.gridsterConfig.api) { // this.gridsterConfig.api.optionsChanged(); // } // } } onWidgetChange(widget) { // this could happen when changes are being made on a widget that is being removed if (!this.dashboard.widgets[widget.id]) { return; } this.updateWidget(widget); } updateWidget(widget) { let dashboard = this.dashboard; if (!this.dashboard.positions[widget.id] && this.gridsterConfig?.api) { const gridsterItem = this.gridsterConfig.api.getFirstPossiblePosition?.({ x: 0, y: 0, rows: this.gridsterConfig?.defaultItemRows, cols: this.gridsterConfig?.defaultItemCols, }); dashboard = (0, bits_1.immutableSet)(dashboard, `positions.${widget.id}`, gridsterItem); } dashboard = (0, bits_1.immutableSet)(dashboard, `widgets.${widget.id}`, widget); this.dashboardBuffer = dashboard; this.dashboardChange.emit(dashboard); } removeWidget(widgetId, removePosition = true) { let dashboard = this.dashboard; if (!dashboard.widgets[widgetId]) { return; } const widgetsClone = Object.assign({}, dashboard.widgets); delete widgetsClone[widgetId]; dashboard = (0, bits_1.immutableSet)(dashboard, "widgets", widgetsClone); if (removePosition) { const positionsClone = Object.assign({}, dashboard.positions); delete positionsClone[widgetId]; dashboard = (0, bits_1.immutableSet)(dashboard, "positions", positionsClone); } this.dashboardChange.emit(dashboard); } shouldWidgetRender(key) { return this.belowFoldLazyLoadingConfig?.enabled ? this.gridsterItemsVisibilityMap[key] : true; } hookEvent(options, eventName, invoke) { const prevEvent = options[eventName]; options[eventName] = (item, itemComponent) => { invoke(item, itemComponent); if (prevEvent) { prevEvent(item, itemComponent); } }; } calculateWidgetsVisibility() { if (!this.belowFoldLazyLoadingConfig?.enabled) { return; } const gridsterRect = this.gridster.el.getBoundingClientRect(); this.gridsterItemsVisibilityMap = this.gridsterItems.reduce((acc, next) => { const { el } = next; const idx = next.widgetId; // if widget is already loaded don't hide it if (!this.belowFoldLazyLoadingConfig.configuration ?.reloadWidgetsOnScroll) { const prevVisibility = acc[idx]; if (prevVisibility) { return acc; } } const rect = el.getBoundingClientRect(); const getHeightVisibility = () => (rect.top > gridsterRect.top && rect.top < gridsterRect.bottom) || (rect.bottom > gridsterRect.top && rect.bottom < gridsterRect.bottom); const getWidthVisibility = () => (rect.left > gridsterRect.left && rect.left < gridsterRect.right) || (rect.right > gridsterRect.left && rect.right < gridsterRect.right); const isVisible = getHeightVisibility() && getWidthVisibility(); acc[idx] = isVisible; return acc; }, this.gridsterItemsVisibilityMap); } }; exports.DashboardComponent = DashboardComponent; tslib_1.__decorate([ (0, core_1.Input)(), tslib_1.__metadata("design:type", Object) ], DashboardComponent.prototype, "gridsterConfig", void 0); tslib_1.__decorate([ (0, core_1.Input)(), tslib_1.__metadata("design:type", Object), tslib_1.__metadata("design:paramtypes", [Object]) ], DashboardComponent.prototype, "dashboard", null); tslib_1.__decorate([ (0, core_1.Input)(), tslib_1.__metadata("design:type", Object) ], DashboardComponent.prototype, "editMode", void 0); tslib_1.__decorate([ (0, core_1.Input)(), tslib_1.__metadata("design:type", Object) ], DashboardComponent.prototype, "belowFoldLazyLoadingConfig", void 0); tslib_1.__decorate([ (0, core_1.Output)(), tslib_1.__metadata("design:type", Object) ], DashboardComponent.prototype, "gridsterConfigChange", void 0); tslib_1.__decorate([ (0, core_1.Output)(), tslib_1.__metadata("design:type", Object) ], DashboardComponent.prototype, "dashboardChange", void 0); tslib_1.__decorate([ (0, core_1.HostBinding)("class.nui-dashboard"), tslib_1.__metadata("design:type", Boolean), tslib_1.__metadata("design:paramtypes", []) ], DashboardComponent.prototype, "hostClass", null); tslib_1.__decorate([ (0, core_1.ViewChild)(angular_gridster2_1.GridsterComponent), tslib_1.__metadata("design:type", angular_gridster2_1.GridsterComponent) ], DashboardComponent.prototype, "gridster", void 0); tslib_1.__decorate([ (0, core_1.ViewChildren)(angular_gridster2_1.GridsterItemComponent), tslib_1.__metadata("design:type", core_1.QueryList) ], DashboardComponent.prototype, "gridsterItems", void 0); exports.DashboardComponent = DashboardComponent = tslib_1.__decorate([ (0, core_1.Component)({ selector: "nui-dashboard", templateUrl: "./dashboard.component.html", styleUrls: ["./dashboard.component.less"], encapsulation: core_1.ViewEncapsulation.None, providers: [ { provide: types_2.DASHBOARD_EVENT_BUS, useClass: bits_1.EventBus, }, ], }), tslib_1.__param(0, (0, core_1.Inject)(types_2.DASHBOARD_EVENT_BUS)), tslib_1.__metadata("design:paramtypes", [bits_1.EventBus]) ], DashboardComponent); //# sourceMappingURL=dashboard.component.js.map