Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3e70f85644 | ||
|
|
482805b5cf | ||
|
|
ffda17e6b1 | ||
|
|
7396843bc6 | ||
|
|
4f75ecb3e0 | ||
|
|
7c1a487114 | ||
|
|
47e9fb92e3 | ||
|
|
7f735dcada | ||
|
|
bd315f42a3 | ||
|
|
e8c1f46430 | ||
|
|
fa96ca81bd | ||
|
|
c384f44c0c | ||
|
|
50df914ca9 | ||
|
|
e0bd888c45 | ||
|
|
02b82fcaf8 | ||
|
|
557afc348f | ||
|
|
1dec787062 | ||
|
|
8853cf75cf | ||
|
|
ad57f11f8a |
@@ -1,8 +1,9 @@
|
||||
export class ReportBuilder {
|
||||
public report_id: number;
|
||||
public report_name:string;
|
||||
public description: string;
|
||||
public report_tags: string;
|
||||
public servicename:string;
|
||||
|
||||
public report_name: string;
|
||||
public description: string;
|
||||
public report_tags: string;
|
||||
public servicename: string;
|
||||
// Add SureConnect reference
|
||||
public sureConnectId: number | null;
|
||||
}
|
||||
@@ -23,8 +23,22 @@ export interface DashboardContentModel {
|
||||
component?: any;
|
||||
name: string;
|
||||
type?:string;
|
||||
// Common properties
|
||||
// Chart properties
|
||||
xAxis?: string;
|
||||
yAxis?: string | string[];
|
||||
chartType?: string;
|
||||
charttitle?: string;
|
||||
chartlegend?: boolean;
|
||||
showlabel?: boolean;
|
||||
chartcolor?: boolean;
|
||||
slices?: boolean;
|
||||
donut?: boolean;
|
||||
charturl?: string;
|
||||
chartparameter?: string;
|
||||
datastore?: string;
|
||||
table?: string;
|
||||
datasource?: string;
|
||||
fieldName?: string;
|
||||
connection?: string;
|
||||
baseFilters?: any[];
|
||||
// Common filter properties
|
||||
@@ -37,6 +51,11 @@ export interface DashboardContentModel {
|
||||
drilldownParameter?: string;
|
||||
drilldownFilters?: any[];
|
||||
drilldownLayers?: any[];
|
||||
// Compact filter properties
|
||||
filterKey?: string;
|
||||
filterType?: string;
|
||||
filterLabel?: string;
|
||||
filterOptions?: string[];
|
||||
}
|
||||
|
||||
export interface DashboardModel {
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>gaurav</title>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>this is h1</h1>
|
||||
<h2>this is h1</h2>
|
||||
<h3>this is h1</h3>
|
||||
<h4>this is h1</h4>
|
||||
<p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ipsa fuga, asperiores mollitia iste vitae repellendus adipisci atque eum corrupti ad placeat unde voluptatum quia perferendis neque expedita, sequi iure quo. Ut error adipisci ex cum sint, suscipit, voluptatem repellat nemo dolorum unde dolores quasi aut. A earum quo mollitia voluptatibus!</p>
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
@@ -79,7 +79,12 @@
|
||||
|
||||
<!-- Multi-Select Filter -->
|
||||
<div class="filter-control" *ngIf="filterType === 'multiselect'">
|
||||
<div class="compact-multiselect-checkboxes" style="max-height: 200px; overflow-y: auto; border: 1px solid #ddd; padding: 10px;">
|
||||
<div class="compact-multiselect-display" (click)="toggleMultiselectDropdown()" style="padding: 5px; border: 1px solid #ddd; cursor: pointer; background-color: #f8f8f8;">
|
||||
<span *ngIf="filterValue && filterValue.length > 0">{{ filterValue.length }} selected</span>
|
||||
<span *ngIf="!filterValue || filterValue.length === 0">{{ filterLabel || filterKey || 'Select options' }}</span>
|
||||
<clr-icon shape="caret down" style="float: right; margin-top: 3px;"></clr-icon>
|
||||
</div>
|
||||
<div class="compact-multiselect-dropdown" *ngIf="showMultiselectDropdown" style="max-height: 200px; overflow-y: auto; border: 1px solid #ddd; border-top: none; padding: 10px; background-color: white; position: absolute; z-index: 1000; width: calc(100% - 2px); box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
|
||||
<div *ngFor="let option of filterOptions" class="clr-checkbox-wrapper" style="margin-bottom: 5px;">
|
||||
<input type="checkbox"
|
||||
[id]="'multiselect-' + option"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component, OnInit, Input, Output, EventEmitter, OnChanges, SimpleChanges } from '@angular/core';
|
||||
import { Component, OnInit, Input, Output, EventEmitter, OnChanges, SimpleChanges, OnDestroy } from '@angular/core';
|
||||
import { FilterService, Filter } from './filter.service';
|
||||
import { AlertsService } from 'src/app/services/fnd/alerts.service';
|
||||
|
||||
@@ -7,7 +7,7 @@ import { AlertsService } from 'src/app/services/fnd/alerts.service';
|
||||
templateUrl: './compact-filter.component.html',
|
||||
styleUrls: ['./compact-filter.component.scss']
|
||||
})
|
||||
export class CompactFilterComponent implements OnInit, OnChanges {
|
||||
export class CompactFilterComponent implements OnInit, OnChanges, OnDestroy {
|
||||
@Input() filterKey: string = '';
|
||||
@Input() filterType: string = 'text';
|
||||
@Input() filterOptions: string[] = [];
|
||||
@@ -23,6 +23,9 @@ export class CompactFilterComponent implements OnInit, OnChanges {
|
||||
availableKeys: string[] = [];
|
||||
availableValues: string[] = [];
|
||||
|
||||
// Multiselect dropdown state
|
||||
showMultiselectDropdown: boolean = false;
|
||||
|
||||
// Configuration properties
|
||||
isConfigMode: boolean = false;
|
||||
configFilterKey: string = '';
|
||||
@@ -73,6 +76,24 @@ export class CompactFilterComponent implements OnInit, OnChanges {
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
// If filterKey changes, clear the previous filter value and remove old filter from service
|
||||
if (changes.filterKey) {
|
||||
// Clear the previous filter value
|
||||
this.filterValue = '';
|
||||
|
||||
// Clear filter options
|
||||
this.filterOptions = [];
|
||||
|
||||
// Clear available values
|
||||
this.availableValues = [];
|
||||
|
||||
// If we had a previous selected filter, clear its value in the service
|
||||
if (this.selectedFilter && changes.filterKey.previousValue) {
|
||||
const oldFilterId = changes.filterKey.previousValue;
|
||||
this.filterService.updateFilterValue(oldFilterId, '');
|
||||
}
|
||||
}
|
||||
|
||||
// If filterKey or filterType changes, re-register the filter
|
||||
if (changes.filterKey || changes.filterType) {
|
||||
// Load available values for the current filter key if it's a dropdown or multiselect
|
||||
@@ -201,6 +222,14 @@ export class CompactFilterComponent implements OnInit, OnChanges {
|
||||
this.onFilterValueChange(dateRange);
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
// Component cleanup - remove this filter from the filter service
|
||||
if (this.selectedFilter) {
|
||||
// Use the proper removeFilter method which handles both filter definition and state
|
||||
this.filterService.removeFilter(this.selectedFilter.id);
|
||||
}
|
||||
}
|
||||
|
||||
// Load available keys from API
|
||||
loadAvailableKeys(): void {
|
||||
if (this.apiUrl) {
|
||||
@@ -278,6 +307,9 @@ export class CompactFilterComponent implements OnInit, OnChanges {
|
||||
this.apiUrl = config.apiUrl;
|
||||
this.connectionId = config.connectionId;
|
||||
|
||||
// Clear filter value when changing configuration
|
||||
this.filterValue = '';
|
||||
|
||||
// Load available keys if API URL is provided
|
||||
if (this.apiUrl) {
|
||||
this.loadAvailableKeys();
|
||||
@@ -304,11 +336,23 @@ export class CompactFilterComponent implements OnInit, OnChanges {
|
||||
|
||||
// Handle filter key change in configuration
|
||||
onFilterKeyChange(key: string): void {
|
||||
// Clear the previous filter value when changing keys
|
||||
this.filterValue = '';
|
||||
|
||||
// Clear filter options until new values are loaded
|
||||
this.filterOptions = [];
|
||||
|
||||
this.configFilterKey = key;
|
||||
|
||||
// Load available values for the selected key if it's a dropdown or multiselect
|
||||
if ((this.configFilterType === 'dropdown' || this.configFilterType === 'multiselect') && key) {
|
||||
this.loadAvailableValues(key);
|
||||
}
|
||||
|
||||
// Clear the filter service value for the previous filter key
|
||||
if (this.selectedFilter) {
|
||||
this.filterService.updateFilterValue(this.selectedFilter.id, '');
|
||||
}
|
||||
}
|
||||
|
||||
// Handle API URL change in configuration
|
||||
@@ -375,4 +419,23 @@ export class CompactFilterComponent implements OnInit, OnChanges {
|
||||
// Emit the change event
|
||||
this.onFilterValueChange(this.filterValue);
|
||||
}
|
||||
|
||||
// Add method to toggle multiselect dropdown visibility
|
||||
toggleMultiselectDropdown(): void {
|
||||
this.showMultiselectDropdown = !this.showMultiselectDropdown;
|
||||
|
||||
// Add document click handler to close dropdown when clicking outside
|
||||
if (this.showMultiselectDropdown) {
|
||||
setTimeout(() => {
|
||||
const handleClick = (event: MouseEvent) => {
|
||||
const target = event.target as HTMLElement;
|
||||
if (!target.closest('.compact-multiselect-display') && !target.closest('.compact-multiselect-dropdown')) {
|
||||
this.showMultiselectDropdown = false;
|
||||
document.removeEventListener('click', handleClick);
|
||||
}
|
||||
};
|
||||
document.addEventListener('click', handleClick);
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,8 +7,8 @@
|
||||
</ol> -->
|
||||
|
||||
<div style="display: inline;">
|
||||
<button class="btn componentbtn" (click)="toggleMenu()"><clr-icon shape="plus"></clr-icon>component</button>
|
||||
<button class="btn btn-primary" (click)="openCommonFilterModal()" style="margin-left: 10px;">
|
||||
<button class="btn componentbtn" (click)="toggleMenu()" *ngIf="!fromRunner"><clr-icon shape="plus"></clr-icon>component</button>
|
||||
<button class="btn btn-primary" (click)="openCommonFilterModal()" style="margin-left: 10px;" *ngIf="!fromRunner">
|
||||
<clr-icon shape="filter"></clr-icon> Common Filter
|
||||
</button>
|
||||
<div style="display: inline;">
|
||||
@@ -22,7 +22,7 @@
|
||||
</div>
|
||||
|
||||
<div class="content-container">
|
||||
<nav class="sidenav" *ngIf="toggle" style="width: 16%;">
|
||||
<nav class="sidenav" *ngIf="toggle && !fromRunner" style="width: 16%;">
|
||||
<ul class="nav-list" style="list-style-type: none;">
|
||||
<li *ngFor="let widget of WidgetsMock">
|
||||
|
||||
@@ -42,14 +42,14 @@
|
||||
<gridster [options]="options" (drop)="onDrop($event)" style="background-color: transparent;">
|
||||
<gridster-item [item]="item" *ngFor="let item of dashboardArray">
|
||||
<!-- <ng-container *ngIf="addToDashboard && item.addToDashboard"> -->
|
||||
<button class="btn btn-icon btn-danger" style="margin-left: 10px; margin-top: 10px;" (click)="removeItem(item)">
|
||||
<button class="btn btn-icon btn-danger" style="margin-left: 10px; margin-top: 10px;" (click)="removeItem(item)" *ngIf="!fromRunner">
|
||||
<clr-icon shape="trash"></clr-icon>
|
||||
</button>
|
||||
<button class="btn btn-icon drag-handler" style="margin-left: 10px; margin-top: 10px;">
|
||||
<button class="btn btn-icon drag-handler" style="margin-left: 10px; margin-top: 10px;" *ngIf="!fromRunner">
|
||||
<clr-icon shape="drag-handle"></clr-icon>
|
||||
</button>
|
||||
|
||||
<button class="btn btn-icon" style="margin-top: 10px; float: right;">
|
||||
<button class="btn btn-icon" style="margin-top: 10px; float: right;" *ngIf="!fromRunner">
|
||||
<input type="checkbox" clrToggle [(ngModel)]="item.addToDashboard" name="addToDashboardSwitch"
|
||||
(change)="toggleAddToDashboard(item)" />
|
||||
</button>
|
||||
@@ -57,7 +57,7 @@
|
||||
<!-- <label for="workflow_name">Add to Dasboard</label>
|
||||
<input class="btn btn-icon" style="margin-top: 10px;float: right;" type="checkbox" clrToggle value="billable" name="billable" />
|
||||
-->
|
||||
<button class="btn btn-icon" style="margin-top: 10px;float: right;" (click)="editGadget(item)">
|
||||
<button class="btn btn-icon" style="margin-top: 10px;float: right;" (click)="editGadget(item)" *ngIf="!fromRunner">
|
||||
<clr-icon shape="pencil"></clr-icon>
|
||||
</button>
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
</div>
|
||||
<div style="text-align: center;">
|
||||
<button class="btn btn-outline" (click)="goBack()">Back</button>
|
||||
<button type="submit" class="btn btn-primary btn-adddata " (click)="UpdateLine()">
|
||||
<button type="submit" class="btn btn-primary btn-adddata " (click)="UpdateLine()" *ngIf="!fromRunner">
|
||||
<b>Update</b>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -26,6 +26,10 @@ import { SureconnectService } from '../sureconnect/sureconnect.service';
|
||||
import { CommonFilterComponent } from '../common-filter/common-filter.component';
|
||||
// Add the CompactFilterComponent import
|
||||
import { CompactFilterComponent } from '../common-filter';
|
||||
// Add the FilterService import
|
||||
import { FilterService } from '../common-filter/filter.service';
|
||||
// Add the UnifiedChartComponent import
|
||||
import { UnifiedChartComponent } from '../gadgets/unified-chart';
|
||||
|
||||
function isNullArray(arr) {
|
||||
return !Array.isArray(arr) || arr.length === 0;
|
||||
@@ -110,6 +114,10 @@ export class EditnewdashComponent implements OnInit {
|
||||
{
|
||||
name: 'Compact Filter',
|
||||
identifier: 'compact_filter'
|
||||
},
|
||||
{
|
||||
name: 'Unified Chart',
|
||||
identifier: 'unified_chart'
|
||||
}
|
||||
]
|
||||
|
||||
@@ -135,7 +143,8 @@ export class EditnewdashComponent implements OnInit {
|
||||
{ name: "Financial Chart", componentInstance: FinancialChartComponent },
|
||||
{ name: "To Do Chart", componentInstance: ToDoChartComponent },
|
||||
{ name: "Grid View", componentInstance: GridViewComponent },
|
||||
{ name: "Compact Filter", componentInstance: CompactFilterComponent }, // Add this line
|
||||
{ name: "Compact Filter", componentInstance: CompactFilterComponent },
|
||||
{ name: "Unified Chart", componentInstance: UnifiedChartComponent },
|
||||
];
|
||||
model: any;
|
||||
linesdata: any;
|
||||
@@ -168,6 +177,7 @@ export class EditnewdashComponent implements OnInit {
|
||||
yAxis: '',
|
||||
xAxis: '',
|
||||
connection: '', // Add connection field
|
||||
chartType: '', // Add chartType field
|
||||
// Drilldown configuration properties (base level)
|
||||
drilldownEnabled: false,
|
||||
drilldownApiUrl: '',
|
||||
@@ -203,9 +213,15 @@ export class EditnewdashComponent implements OnInit {
|
||||
private _fb: FormBuilder,
|
||||
private datastoreService: DatastoreService,
|
||||
private alertService: AlertsService,
|
||||
private sureconnectService: SureconnectService) { } // Add SureconnectService to constructor
|
||||
private sureconnectService: SureconnectService,
|
||||
private filterService: FilterService) { } // Add SureconnectService and FilterService to constructor
|
||||
|
||||
// Add property to track if coming from dashboard runner
|
||||
fromRunner: boolean = false;
|
||||
|
||||
ngOnInit(): void {
|
||||
// Reset the filter service when the component is initialized
|
||||
this.filterService.resetFilters();
|
||||
|
||||
// Grid options
|
||||
this.options = {
|
||||
@@ -231,6 +247,13 @@ export class EditnewdashComponent implements OnInit {
|
||||
itemResizeCallback: this.itemResize.bind(this)
|
||||
};
|
||||
|
||||
// Check if coming from dashboard runner
|
||||
this.route.queryParams.subscribe(params => {
|
||||
if (params['fromRunner'] === 'true') {
|
||||
this.fromRunner = true;
|
||||
}
|
||||
});
|
||||
|
||||
this.editId = this.route.snapshot.params.id;
|
||||
console.log(this.editId);
|
||||
this.dashboardService.getById(this.editId).subscribe((data) => {
|
||||
@@ -317,6 +340,9 @@ export class EditnewdashComponent implements OnInit {
|
||||
dashboardLine: any;
|
||||
dashboardName: any;
|
||||
getData() {
|
||||
// Reset the filter service when switching between dashboard records
|
||||
this.filterService.resetFilters();
|
||||
|
||||
// We get the id in get current router dashboard/:id
|
||||
this.route.params.subscribe(params => {
|
||||
// + is used to cast string to int
|
||||
@@ -435,7 +461,17 @@ export class EditnewdashComponent implements OnInit {
|
||||
|
||||
onDrop(ev) {
|
||||
const componentType = ev.dataTransfer.getData("widgetIdentifier");
|
||||
let maxChartId = this.dashboardArray?.reduce((maxId, item) => Math.max(maxId, item.chartid), 0);
|
||||
// Safely calculate maxChartId, handling cases where chartid might be NaN or missing
|
||||
let maxChartId = 0;
|
||||
if (this.dashboardArray && this.dashboardArray.length > 0) {
|
||||
const validChartIds = this.dashboardArray
|
||||
.map(item => item.chartid)
|
||||
.filter(chartid => typeof chartid === 'number' && !isNaN(chartid));
|
||||
|
||||
if (validChartIds.length > 0) {
|
||||
maxChartId = Math.max(...validChartIds);
|
||||
}
|
||||
}
|
||||
switch (componentType) {
|
||||
case "radar_chart":
|
||||
return this.dashboardArray.push({
|
||||
@@ -582,6 +618,22 @@ export class EditnewdashComponent implements OnInit {
|
||||
component: GridViewComponent,
|
||||
name: "Grid View"
|
||||
});
|
||||
case "unified_chart":
|
||||
return this.dashboardArray.push({
|
||||
cols: 5,
|
||||
rows: 6,
|
||||
x: 0,
|
||||
y: 0,
|
||||
chartid: maxChartId + 1,
|
||||
component: UnifiedChartComponent,
|
||||
name: "Unified Chart",
|
||||
// Add default configuration for unified chart
|
||||
chartType: 'bar',
|
||||
xAxis: '',
|
||||
yAxis: '',
|
||||
table: '',
|
||||
connection: undefined
|
||||
});
|
||||
}
|
||||
}
|
||||
removeItem(item) {
|
||||
@@ -599,6 +651,12 @@ export class EditnewdashComponent implements OnInit {
|
||||
modelid: number;
|
||||
// Update the editGadget method to initialize filter properties
|
||||
editGadget(item) {
|
||||
// If coming from dashboard runner, skip showing the config modal
|
||||
if (this.fromRunner) {
|
||||
console.log('Coming from dashboard runner, skipping config modal');
|
||||
return;
|
||||
}
|
||||
|
||||
this.modeledit = true;
|
||||
this.modelid = item.chartid;
|
||||
console.log(this.modelid);
|
||||
@@ -628,6 +686,10 @@ export class EditnewdashComponent implements OnInit {
|
||||
if (item['filterOptions'] === undefined) {
|
||||
this.gadgetsEditdata['filterOptions'] = [];
|
||||
}
|
||||
// Initialize chartType property if not present (for unified chart)
|
||||
if (item['chartType'] === undefined) {
|
||||
this.gadgetsEditdata['chartType'] = 'bar';
|
||||
}
|
||||
|
||||
// Initialize filterOptionsString for compact filter
|
||||
if (item.name === 'Compact Filter') {
|
||||
@@ -734,15 +796,34 @@ export class EditnewdashComponent implements OnInit {
|
||||
this.refreshBaseDrilldownColumns();
|
||||
}
|
||||
|
||||
if (item.datastore !== undefined || '' || null) {
|
||||
// Check if we have either datastore or table to fetch columns
|
||||
if ((item.datastore !== undefined && item.datastore !== '' && item.datastore !== null) ||
|
||||
(item.table !== undefined && item.table !== '' && item.table !== null)) {
|
||||
const datastore = item.datastore;
|
||||
this.getTables(datastore);
|
||||
const table = item.table;
|
||||
this.getColumns(datastore, table);
|
||||
|
||||
// Fetch tables if datastore is available
|
||||
if (datastore) {
|
||||
this.getTables(datastore);
|
||||
}
|
||||
|
||||
// Fetch columns if table is available
|
||||
if (table) {
|
||||
this.getColumns(datastore, table);
|
||||
}
|
||||
|
||||
console.log(item.yAxis);
|
||||
if (isArray(item.yAxis)) {
|
||||
this.selectedyAxis = item.yAxis;
|
||||
// Set selectedyAxis regardless of whether it's an array or string
|
||||
if (item.yAxis !== undefined && item.yAxis !== '' && item.yAxis !== null) {
|
||||
if (isArray(item.yAxis)) {
|
||||
this.selectedyAxis = item.yAxis;
|
||||
} else {
|
||||
// For single yAxis values, convert to array
|
||||
this.selectedyAxis = [item.yAxis];
|
||||
}
|
||||
console.log(this.selectedyAxis);
|
||||
} else {
|
||||
this.selectedyAxis = [];
|
||||
}
|
||||
} else {
|
||||
this.selectedyAxis = [];
|
||||
@@ -816,12 +897,29 @@ export class EditnewdashComponent implements OnInit {
|
||||
// Update the onSubmit method to properly save filter data
|
||||
onSubmit(id) {
|
||||
console.log(id);
|
||||
if (!isNullArray(this.selectedyAxis)) {
|
||||
console.log("get y-axis array", this.selectedyAxis);
|
||||
|
||||
// Check if ID is valid, including handling NaN
|
||||
if (id === null || id === undefined || isNaN(id)) {
|
||||
console.warn('Chart ID is null, undefined, or NaN, using modelid instead:', this.modelid);
|
||||
id = this.modelid;
|
||||
}
|
||||
|
||||
// Ensure we have a valid numeric ID
|
||||
const numId = typeof id === 'number' ? id : parseInt(id, 10);
|
||||
if (isNaN(numId)) {
|
||||
console.error('Unable to determine valid chart ID, aborting onSubmit');
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle both array and string yAxis values
|
||||
if (this.selectedyAxis !== undefined && this.selectedyAxis !== null &&
|
||||
((Array.isArray(this.selectedyAxis) && this.selectedyAxis.length > 0) ||
|
||||
(typeof this.selectedyAxis === 'string' && this.selectedyAxis !== ''))) {
|
||||
console.log("get y-axis", this.selectedyAxis);
|
||||
this.entryForm.patchValue({ yAxis: this.selectedyAxis });
|
||||
}
|
||||
let formdata = this.entryForm.value;
|
||||
let num = id;
|
||||
let num = numId;
|
||||
console.log(this.entryForm.value);
|
||||
this.dashboardCollection.dashboard = this.dashboardCollection.dashboard.map(item => {
|
||||
if (item.chartid == num) {
|
||||
@@ -860,6 +958,11 @@ export class EditnewdashComponent implements OnInit {
|
||||
xyz.connection = this.gadgetsEditdata.connection || undefined;
|
||||
}
|
||||
|
||||
// For unified chart, preserve chart configuration properties
|
||||
if (item.name === 'Unified Chart') {
|
||||
xyz.chartType = this.gadgetsEditdata.chartType || 'bar';
|
||||
}
|
||||
|
||||
console.log(xyz);
|
||||
return xyz;
|
||||
}
|
||||
@@ -943,6 +1046,48 @@ export class EditnewdashComponent implements OnInit {
|
||||
return commonFilterInputs;
|
||||
}
|
||||
|
||||
// For UnifiedChartComponent, pass chart properties with chartType
|
||||
if (item.name === 'Unified Chart') {
|
||||
const unifiedChartInputs = {
|
||||
chartType: item.chartType || 'bar',
|
||||
xAxis: item.xAxis,
|
||||
yAxis: item.yAxis,
|
||||
table: item.table,
|
||||
datastore: item.datastore,
|
||||
charttitle: item.charttitle,
|
||||
chartlegend: item.chartlegend,
|
||||
showlabel: item.showlabel,
|
||||
chartcolor: item.chartcolor,
|
||||
slices: item.slices,
|
||||
donut: item.donut,
|
||||
charturl: item.charturl,
|
||||
chartparameter: item.chartparameter,
|
||||
datasource: item.datasource,
|
||||
fieldName: item.name, // Using item.name as fieldName
|
||||
connection: item['connection'], // Add connection field using bracket notation
|
||||
// Base drilldown configuration properties
|
||||
drilldownEnabled: item['drilldownEnabled'],
|
||||
drilldownApiUrl: item['drilldownApiUrl'],
|
||||
// Removed drilldownParameterKey since we're using URL templates
|
||||
drilldownXAxis: item['drilldownXAxis'],
|
||||
drilldownYAxis: item['drilldownYAxis'],
|
||||
drilldownParameter: item['drilldownParameter'], // Add drilldown parameter
|
||||
baseFilters: item['baseFilters'] || [], // Add base filters
|
||||
drilldownFilters: item['drilldownFilters'] || [], // Add drilldown filters
|
||||
// Multi-layer drilldown configurations
|
||||
drilldownLayers: item['drilldownLayers'] || []
|
||||
};
|
||||
|
||||
// Remove undefined properties to avoid passing unnecessary data
|
||||
Object.keys(unifiedChartInputs).forEach(key => {
|
||||
if (unifiedChartInputs[key] === undefined) {
|
||||
delete unifiedChartInputs[key];
|
||||
}
|
||||
});
|
||||
|
||||
return unifiedChartInputs;
|
||||
}
|
||||
|
||||
// For GridViewComponent, pass chart properties with drilldown support
|
||||
if (item.component && item.component.name === 'GridViewComponent') {
|
||||
const gridInputs = {
|
||||
@@ -1028,15 +1173,25 @@ export class EditnewdashComponent implements OnInit {
|
||||
applyChanges(id) {
|
||||
console.log('Apply changes for chart ID:', id);
|
||||
|
||||
// Check if ID is valid
|
||||
if (id === null || id === undefined) {
|
||||
console.warn('Chart ID is null or undefined, using modelid instead:', this.modelid);
|
||||
// Check if ID is valid, including handling NaN
|
||||
if (id === null || id === undefined || isNaN(id)) {
|
||||
console.warn('Chart ID is null, undefined, or NaN, using modelid instead:', this.modelid);
|
||||
id = this.modelid;
|
||||
}
|
||||
|
||||
// Update the form with selected Y-axis values if it's an array
|
||||
if (!isNullArray(this.selectedyAxis)) {
|
||||
console.log("get y-axis array", this.selectedyAxis);
|
||||
// Ensure we have a valid numeric ID
|
||||
const numId = typeof id === 'number' ? id : parseInt(id, 10);
|
||||
if (isNaN(numId)) {
|
||||
console.error('Unable to determine valid chart ID, aborting applyChanges');
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the form with selected Y-axis values
|
||||
// Handle both array and string yAxis values
|
||||
if (this.selectedyAxis !== undefined && this.selectedyAxis !== null &&
|
||||
((Array.isArray(this.selectedyAxis) && this.selectedyAxis.length > 0) ||
|
||||
(typeof this.selectedyAxis === 'string' && this.selectedyAxis !== ''))) {
|
||||
console.log("get y-axis", this.selectedyAxis);
|
||||
this.entryForm.patchValue({ yAxis: this.selectedyAxis });
|
||||
}
|
||||
|
||||
@@ -1127,6 +1282,9 @@ export class EditnewdashComponent implements OnInit {
|
||||
|
||||
// Note: We don't close the modal here, allowing the user to make additional changes
|
||||
// The user can click "Save" when they're done with all changes
|
||||
|
||||
// Reset the filter service to ensure clean state
|
||||
this.filterService.resetFilters();
|
||||
}
|
||||
|
||||
goBack() {
|
||||
|
||||
@@ -279,19 +279,32 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- No data message -->
|
||||
<div *ngIf="noDataAvailable" style="text-align: center; padding: 20px; color: #666; font-style: italic;">
|
||||
No data available
|
||||
</div>
|
||||
<!-- Chart container -->
|
||||
<div style="position: relative; height: calc(100% - 80px); width: 100%; padding: 0 10px 30px 10px;">
|
||||
<!-- Loading indicator -->
|
||||
<div *ngIf="!dataLoaded" style="text-align: center; padding: 20px; color: #666; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 10; width: 100%;">
|
||||
Loading data...
|
||||
</div>
|
||||
|
||||
<!-- Chart display -->
|
||||
<div *ngIf="!noDataAvailable" style="position: relative; height: calc(100% - 50px);">
|
||||
<!-- No data message -->
|
||||
<div *ngIf="dataLoaded && (noDataAvailable || !isChartDataValid())" style="text-align: center; padding: 20px; color: #666; font-style: italic; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 10; width: 100%;">
|
||||
No data available
|
||||
</div>
|
||||
|
||||
<!-- Chart display - Always render the canvas but conditionally show/hide with CSS -->
|
||||
<canvas baseChart
|
||||
[datasets]="bubbleChartData"
|
||||
[type]="bubbleChartType"
|
||||
[options]="bubbleChartOptions"
|
||||
(chartHover)="chartHovered($event)"
|
||||
(chartClick)="chartClicked($event)">
|
||||
(chartClick)="chartClicked($event)"
|
||||
[style.visibility]="dataLoaded && !noDataAvailable && isChartDataValid() ? 'visible' : 'hidden'"
|
||||
[style.position]="'absolute'"
|
||||
[style.top]="'0'"
|
||||
[style.left]="'0'"
|
||||
[style.height]="'100%'"
|
||||
[style.width]="'100%'"
|
||||
[style.padding]="'0 10px 20px 10px'">
|
||||
</canvas>
|
||||
</div>
|
||||
</div>
|
||||
@@ -37,55 +37,77 @@ export class BubbleChartComponent implements OnInit, OnChanges {
|
||||
@Input() drilldownLayers: any[] = []; // Array of drilldown layer configurations
|
||||
|
||||
public bubbleChartOptions: ChartConfiguration['options'] = {
|
||||
// scales: {
|
||||
// x: {
|
||||
// min: 0,
|
||||
// max: 30,
|
||||
// ticks: {}
|
||||
// },
|
||||
// y: {
|
||||
// min: 0,
|
||||
// max: 30,
|
||||
// ticks: {}
|
||||
// },
|
||||
// plugins: {
|
||||
// title: {
|
||||
// display: true,
|
||||
// text: 'Bubble Chart'
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
scales: {
|
||||
x: {
|
||||
beginAtZero: true,
|
||||
title: {
|
||||
display: true,
|
||||
text: 'X Axis'
|
||||
},
|
||||
ticks: {
|
||||
autoSkip: false,
|
||||
maxRotation: 45,
|
||||
minRotation: 45
|
||||
}
|
||||
},
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Y Axis'
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
legend: {
|
||||
display: true,
|
||||
position: 'top',
|
||||
},
|
||||
tooltip: {
|
||||
enabled: true,
|
||||
mode: 'point',
|
||||
intersect: false,
|
||||
callbacks: {
|
||||
label: function(context: any) {
|
||||
const point: any = context.raw;
|
||||
if (point && point.hasOwnProperty('y') && point.hasOwnProperty('r')) {
|
||||
const yValue = parseFloat(point.y);
|
||||
const rValue = parseFloat(point.r);
|
||||
if (!isNaN(yValue) && !isNaN(rValue)) {
|
||||
return `Value: ${yValue.toFixed(2)}, Size: ${rValue.toFixed(1)}`;
|
||||
}
|
||||
}
|
||||
return context.dataset.label || '';
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
animation: {
|
||||
duration: 800,
|
||||
easing: 'easeInOutQuart'
|
||||
},
|
||||
// Enable individual point styling
|
||||
elements: {
|
||||
point: {
|
||||
hoverRadius: 12,
|
||||
hoverBorderWidth: 3
|
||||
}
|
||||
},
|
||||
// Add padding to ensure x-axis labels are visible
|
||||
layout: {
|
||||
padding: {
|
||||
left: 10,
|
||||
right: 10,
|
||||
top: 10,
|
||||
bottom: 30
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public bubbleChartType: string = 'bubble';
|
||||
public bubbleChartData: ChartDataset[] = [
|
||||
{
|
||||
data: [
|
||||
{ x: 10, y: 10, r: 10 },
|
||||
{ x: 15, y: 5, r: 15 },
|
||||
{ x: 26, y: 12, r: 23 },
|
||||
{ x: 7, y: 8, r: 8 },
|
||||
],
|
||||
label: 'Investment Equities',
|
||||
backgroundColor: 'rgba(255, 0, 0, 0.6)', // Red
|
||||
borderColor: 'blue',
|
||||
hoverBackgroundColor: 'purple',
|
||||
hoverBorderColor: 'red',
|
||||
},
|
||||
{
|
||||
data: [
|
||||
{ x: 5, y: 15, r: 12 },
|
||||
{ x: 20, y: 7, r: 8 },
|
||||
{ x: 12, y: 18, r: 15 },
|
||||
{ x: 8, y: 6, r: 10 },
|
||||
],
|
||||
label: 'Investment Bonds',
|
||||
backgroundColor: 'rgba(0, 255, 0, 0.6)', // Green
|
||||
borderColor: 'green',
|
||||
hoverBackgroundColor: 'yellow',
|
||||
hoverBorderColor: 'blue',
|
||||
},
|
||||
];
|
||||
public bubbleChartData: ChartDataset[] = [];
|
||||
|
||||
// Multi-layer drilldown state tracking
|
||||
drilldownStack: any[] = []; // Stack to track drilldown navigation history
|
||||
@@ -94,6 +116,7 @@ export class BubbleChartComponent implements OnInit, OnChanges {
|
||||
|
||||
// No data state
|
||||
noDataAvailable: boolean = false;
|
||||
dataLoaded: boolean = false; // Track if data has been loaded
|
||||
|
||||
// Flag to prevent infinite loops
|
||||
private isFetchingData: boolean = false;
|
||||
@@ -465,45 +488,250 @@ export class BubbleChartComponent implements OnInit, OnChanges {
|
||||
this.fetchChartData();
|
||||
}
|
||||
|
||||
// Helper function to replace alpha value in RGBA color string
|
||||
private replaceAlpha(color: string, newAlpha: number): string {
|
||||
// Match rgba(r, g, b, a) format and replace alpha value
|
||||
return color.replace(/rgba\((\d+),\s*(\d+),\s*(\d+),\s*[\d.]+\)/, `rgba($1, $2, $3, ${newAlpha})`);
|
||||
}
|
||||
|
||||
// Function to generate different colors for bubbles
|
||||
private generateBubbleColor(index: number, value: number, total: number): string {
|
||||
// Generate colors based on index or value
|
||||
// Using HSL color model for better color distribution
|
||||
const hue = (index * 137.508) % 360; // Golden angle approximation for good distribution
|
||||
const saturation = 80 + (index % 20); // High saturation for vibrant colors
|
||||
const lightness = 40 + (index % 30); // Vary lightness for contrast
|
||||
|
||||
// Convert HSL to RGB
|
||||
const h = hue / 360;
|
||||
const s = saturation / 100;
|
||||
const l = lightness / 100;
|
||||
|
||||
const rgb = this.hslToRgb(h, s, l);
|
||||
return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 0.7)`;
|
||||
}
|
||||
|
||||
// Helper function to convert HSL to RGB
|
||||
private hslToRgb(h: number, s: number, l: number): { r: number, g: number, b: number } {
|
||||
let r, g, b;
|
||||
|
||||
if (s === 0) {
|
||||
r = g = b = l; // achromatic
|
||||
} else {
|
||||
const hue2rgb = (p: number, q: number, t: number) => {
|
||||
if (t < 0) t += 1;
|
||||
if (t > 1) t -= 1;
|
||||
if (t < 1/6) return p + (q - p) * 6 * t;
|
||||
if (t < 1/2) return q;
|
||||
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
||||
return p;
|
||||
};
|
||||
|
||||
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
||||
const p = 2 * l - q;
|
||||
r = hue2rgb(p, q, h + 1/3);
|
||||
g = hue2rgb(p, q, h);
|
||||
b = hue2rgb(p, q, h - 1/3);
|
||||
}
|
||||
|
||||
return {
|
||||
r: Math.round(r * 255),
|
||||
g: Math.round(g * 255),
|
||||
b: Math.round(b * 255)
|
||||
};
|
||||
}
|
||||
|
||||
// Helper function to calculate logarithmic scaling
|
||||
private logScale(value: number, min: number, max: number, minRadius: number, maxRadius: number): number {
|
||||
if (min === max) return (minRadius + maxRadius) / 2;
|
||||
|
||||
// Normalize value to 0-1 range
|
||||
const normalized = (value - min) / (max - min);
|
||||
|
||||
// Apply logarithmic scaling (base 10)
|
||||
// Add 1 to avoid log(0) and scale to 1-10 range
|
||||
const logValue = Math.log10(normalized * 9 + 1);
|
||||
|
||||
// Scale to desired radius range
|
||||
return minRadius + (logValue / Math.log10(10)) * (maxRadius - minRadius);
|
||||
}
|
||||
|
||||
// Transform data to bubble chart format
|
||||
private transformToBubbleData(labels: any[], data: any[]): ChartDataset[] {
|
||||
// For bubble charts, we need to transform the data into bubble format
|
||||
// Bubble charts expect data in the format: {x: number, y: number, r: number}
|
||||
console.log('Transforming data to bubble format:', { labels, data });
|
||||
|
||||
// Handle null/undefined data
|
||||
if (!labels || !data) {
|
||||
console.log('Labels or data is null/undefined, returning empty dataset');
|
||||
return [];
|
||||
}
|
||||
|
||||
// If we have the expected bubble data format, return it as is
|
||||
if (data && data.length > 0 && data[0].data && data[0].data.length > 0 &&
|
||||
typeof data[0].data[0] === 'object' && data[0].data[0].hasOwnProperty('x') &&
|
||||
data[0].data[0].hasOwnProperty('y') && data[0].data[0].hasOwnProperty('r')) {
|
||||
console.log('Data is already in bubble format, returning as is');
|
||||
return data;
|
||||
}
|
||||
|
||||
// Otherwise, create a default bubble dataset
|
||||
const bubbleDatasets: ChartDataset[] = [
|
||||
{
|
||||
data: [
|
||||
{ x: 10, y: 10, r: 10 },
|
||||
{ x: 15, y: 5, r: 15 },
|
||||
{ x: 26, y: 12, r: 23 },
|
||||
{ x: 7, y: 8, r: 8 },
|
||||
],
|
||||
label: 'Dataset 1',
|
||||
backgroundColor: 'rgba(255, 0, 0, 0.6)',
|
||||
borderColor: 'blue',
|
||||
hoverBackgroundColor: 'purple',
|
||||
hoverBorderColor: 'red',
|
||||
}
|
||||
];
|
||||
// Transform the data properly for bubble chart
|
||||
// Assuming labels are x-values and data[0].data are y-values
|
||||
if (labels && data && data.length > 0 && data[0].data) {
|
||||
console.log('Transforming regular data to bubble format');
|
||||
const yValues = data[0].data;
|
||||
const label = data[0].label || 'Dataset 1';
|
||||
|
||||
return bubbleDatasets;
|
||||
// Handle case where yValues might not be an array
|
||||
if (!Array.isArray(yValues)) {
|
||||
console.log('yValues is not an array, returning empty dataset');
|
||||
return [];
|
||||
}
|
||||
|
||||
console.log('yValues type:', typeof yValues);
|
||||
console.log('yValues length:', yValues.length);
|
||||
console.log('First few yValues:', yValues.slice(0, 5));
|
||||
|
||||
// Find min and max values for scaling
|
||||
let minValue = Infinity;
|
||||
let maxValue = -Infinity;
|
||||
const validYValues = [];
|
||||
|
||||
// First pass: collect valid values and find min/max
|
||||
for (let i = 0; i < yValues.length; i++) {
|
||||
let y;
|
||||
if (typeof yValues[i] === 'string') {
|
||||
y = parseFloat(yValues[i]);
|
||||
} else {
|
||||
y = yValues[i];
|
||||
}
|
||||
|
||||
if (!isNaN(y)) {
|
||||
validYValues.push(y);
|
||||
minValue = Math.min(minValue, y);
|
||||
maxValue = Math.max(maxValue, y);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('Value range:', { minValue, maxValue });
|
||||
|
||||
// Adjust radius range based on number of data points
|
||||
// For fewer points, we can use larger bubbles; for more points, smaller bubbles to prevent overlap
|
||||
const dataPointCount = Math.min(labels.length, yValues.length);
|
||||
let minRadius = 3;
|
||||
let maxRadius = 30;
|
||||
|
||||
// Adjust radius range based on data point count
|
||||
if (dataPointCount > 50) {
|
||||
minRadius = 2;
|
||||
maxRadius = 20;
|
||||
} else if (dataPointCount > 20) {
|
||||
minRadius = 3;
|
||||
maxRadius = 25;
|
||||
}
|
||||
|
||||
console.log('Radius range:', { minRadius, maxRadius, dataPointCount });
|
||||
|
||||
// Create bubble points from labels (x) and data (y)
|
||||
const bubblePoints = [];
|
||||
const bubbleColors = [];
|
||||
const minLength = Math.min(labels.length, yValues.length);
|
||||
|
||||
console.log('Processing data points:', { labels, yValues, minLength });
|
||||
|
||||
for (let i = 0; i < minLength; i++) {
|
||||
// Log each point for debugging
|
||||
console.log(`Processing point ${i}: label=${labels[i]}, yValue=${yValues[i]}, type=${typeof yValues[i]}`);
|
||||
|
||||
// Convert y to number if it's a string
|
||||
let y;
|
||||
if (typeof yValues[i] === 'string') {
|
||||
y = parseFloat(yValues[i]);
|
||||
console.log(`Converted string yValue to number: ${yValues[i]} -> ${y}`);
|
||||
} else {
|
||||
y = yValues[i];
|
||||
}
|
||||
|
||||
// Handle NaN values
|
||||
if (isNaN(y)) {
|
||||
console.log(`Skipping point ${i} due to NaN y value: ${yValues[i]}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Calculate radius based on the y-value with logarithmic scaling
|
||||
const r = this.logScale(y, minValue, maxValue, minRadius, maxRadius);
|
||||
|
||||
console.log(`Value: ${y}, Radius: ${r}`);
|
||||
|
||||
// For x-value, we'll use the index position since labels are strings
|
||||
const x = i;
|
||||
|
||||
// Generate a unique color for this bubble
|
||||
const backgroundColor = this.generateBubbleColor(i, y, minLength);
|
||||
|
||||
// Store the color for the dataset
|
||||
bubbleColors.push(backgroundColor);
|
||||
|
||||
// Add the point
|
||||
const point = {
|
||||
x,
|
||||
y,
|
||||
r
|
||||
};
|
||||
console.log(`Adding point ${i}:`, point);
|
||||
bubblePoints.push(point);
|
||||
}
|
||||
|
||||
console.log('Generated bubble points:', bubblePoints);
|
||||
console.log('Generated bubble points count:', bubblePoints.length);
|
||||
console.log('Generated bubble colors count:', bubbleColors.length);
|
||||
|
||||
// If we have no valid points, return empty array
|
||||
if (bubblePoints.length === 0) {
|
||||
console.log('No valid bubble points generated, returning empty dataset');
|
||||
return [];
|
||||
}
|
||||
|
||||
// Create a single dataset with all bubble points
|
||||
const bubbleDatasets: ChartDataset[] = [
|
||||
{
|
||||
data: bubblePoints,
|
||||
label: label,
|
||||
backgroundColor: bubbleColors,
|
||||
borderColor: bubbleColors.map(color => this.replaceAlpha(color, 1)), // Slightly more opaque border
|
||||
hoverBackgroundColor: bubbleColors.map(color => this.replaceAlpha(color, 0.9)),
|
||||
hoverBorderColor: 'rgba(255, 255, 255, 1)',
|
||||
borderWidth: 2,
|
||||
pointHoverRadius: 10,
|
||||
}
|
||||
];
|
||||
|
||||
console.log('Transformed bubble data:', bubbleDatasets);
|
||||
return bubbleDatasets;
|
||||
}
|
||||
|
||||
console.log('Could not transform data, returning empty dataset');
|
||||
// Return empty dataset instead of default data
|
||||
return [];
|
||||
}
|
||||
|
||||
fetchChartData(): void {
|
||||
// Set flag to prevent recursive calls
|
||||
this.isFetchingData = true;
|
||||
this.dataLoaded = false; // Mark data as not loaded yet
|
||||
this.noDataAvailable = false; // Reset no data flag
|
||||
|
||||
console.log('Starting fetchChartData, current state:', {
|
||||
table: this.table,
|
||||
xAxis: this.xAxis,
|
||||
yAxis: this.yAxis,
|
||||
connection: this.connection
|
||||
});
|
||||
|
||||
// If we're in drilldown mode, fetch the appropriate drilldown data
|
||||
if (this.currentDrilldownLevel > 0 && this.drilldownStack.length > 0) {
|
||||
console.log('Fetching drilldown data');
|
||||
this.fetchDrilldownData();
|
||||
// Reset flag after fetching
|
||||
this.isFetchingData = false;
|
||||
@@ -583,32 +811,82 @@ export class BubbleChartComponent implements OnInit, OnChanges {
|
||||
this.dashboardService.getChartData(this.table, 'bubble', this.xAxis, yAxisString, this.connection, '', '', filterParams).subscribe(
|
||||
(data: any) => {
|
||||
console.log('Received bubble chart data:', data);
|
||||
if (data === null) {
|
||||
console.warn('Bubble chart API returned null data. Check if the API endpoint is working correctly.');
|
||||
this.noDataAvailable = true;
|
||||
this.bubbleChartData = [];
|
||||
// Reset flag after fetching
|
||||
this.isFetchingData = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle the actual data structure returned by the API
|
||||
if (data && data.chartLabels && data.chartData) {
|
||||
// Reset chart data to empty first
|
||||
this.bubbleChartData = [];
|
||||
|
||||
if (data === null || data === undefined) {
|
||||
console.warn('Bubble chart API returned null/undefined data. Check if the API endpoint is working correctly.');
|
||||
this.noDataAvailable = true;
|
||||
} else if (data && data.chartLabels && data.chartData) {
|
||||
// For bubble charts, we need to transform the data into bubble format
|
||||
// Bubble charts expect data in the format: {x: number, y: number, r: number}
|
||||
this.noDataAvailable = data.chartLabels.length === 0;
|
||||
this.bubbleChartData = this.transformToBubbleData(data.chartLabels, data.chartData);
|
||||
console.log('Updated bubble chart with data:', this.bubbleChartData);
|
||||
console.log('Processing chartLabels and chartData format');
|
||||
const transformedData = this.transformToBubbleData(data.chartLabels, data.chartData);
|
||||
console.log('Transformed data:', transformedData);
|
||||
|
||||
// Check if we have valid data
|
||||
let hasValidData = false;
|
||||
if (transformedData && transformedData.length > 0) {
|
||||
for (const dataset of transformedData) {
|
||||
if (dataset.data && dataset.data.length > 0) {
|
||||
hasValidData = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasValidData) {
|
||||
// Create a new array reference to trigger change detection
|
||||
this.bubbleChartData = [...transformedData];
|
||||
this.noDataAvailable = false;
|
||||
console.log('Updated bubble chart with data:', this.bubbleChartData);
|
||||
} else {
|
||||
console.log('No valid data after transformation');
|
||||
this.noDataAvailable = true;
|
||||
}
|
||||
} else if (data && data.labels && data.datasets) {
|
||||
// Handle the original expected format as fallback
|
||||
this.noDataAvailable = data.labels.length === 0;
|
||||
this.bubbleChartData = data.datasets;
|
||||
console.log('Updated bubble chart with legacy data format:', this.bubbleChartData);
|
||||
console.log('Processing labels and datasets format');
|
||||
// Check if we have valid data
|
||||
let hasValidData = false;
|
||||
if (data.datasets && data.datasets.length > 0) {
|
||||
for (const dataset of data.datasets) {
|
||||
if (dataset.data && dataset.data.length > 0) {
|
||||
hasValidData = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasValidData) {
|
||||
// Create a new array reference to trigger change detection
|
||||
this.bubbleChartData = [...data.datasets];
|
||||
this.noDataAvailable = false;
|
||||
console.log('Updated bubble chart with legacy data format:', this.bubbleChartData);
|
||||
} else {
|
||||
console.log('No valid data in legacy format');
|
||||
this.noDataAvailable = true;
|
||||
}
|
||||
} else {
|
||||
console.warn('Bubble chart received data does not have expected structure', data);
|
||||
this.noDataAvailable = true;
|
||||
this.bubbleChartData = [];
|
||||
}
|
||||
|
||||
this.dataLoaded = true; // Mark data as loaded
|
||||
|
||||
console.log('Final state after data fetch:', {
|
||||
noDataAvailable: this.noDataAvailable,
|
||||
dataLoaded: this.dataLoaded,
|
||||
bubbleChartDataLength: this.bubbleChartData.length,
|
||||
isChartDataValid: this.isChartDataValid()
|
||||
});
|
||||
|
||||
// Trigger change detection with a small delay to ensure proper rendering
|
||||
setTimeout(() => {
|
||||
this.forceChartUpdate();
|
||||
}, 100);
|
||||
|
||||
// Reset flag after fetching
|
||||
this.isFetchingData = false;
|
||||
},
|
||||
@@ -616,15 +894,24 @@ export class BubbleChartComponent implements OnInit, OnChanges {
|
||||
console.error('Error fetching bubble chart data:', error);
|
||||
this.noDataAvailable = true;
|
||||
this.bubbleChartData = [];
|
||||
this.dataLoaded = true;
|
||||
// Trigger change detection
|
||||
setTimeout(() => {
|
||||
this.forceChartUpdate();
|
||||
}, 100);
|
||||
// Reset flag after fetching
|
||||
this.isFetchingData = false;
|
||||
// Keep default data in case of error
|
||||
}
|
||||
);
|
||||
} else {
|
||||
console.log('Missing required data for bubble chart:', { table: this.table, xAxis: this.xAxis, yAxis: this.yAxis, connection: this.connection });
|
||||
this.noDataAvailable = true;
|
||||
this.bubbleChartData = [];
|
||||
this.dataLoaded = true;
|
||||
// Trigger change detection
|
||||
setTimeout(() => {
|
||||
this.forceChartUpdate();
|
||||
}, 100);
|
||||
// Reset flag after fetching
|
||||
this.isFetchingData = false;
|
||||
}
|
||||
@@ -654,6 +941,10 @@ export class BubbleChartComponent implements OnInit, OnChanges {
|
||||
console.warn('Invalid drilldown layer index:', layerIndex);
|
||||
this.noDataAvailable = true;
|
||||
this.bubbleChartData = [];
|
||||
this.dataLoaded = true;
|
||||
setTimeout(() => {
|
||||
this.forceChartUpdate();
|
||||
}, 100);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -665,6 +956,10 @@ export class BubbleChartComponent implements OnInit, OnChanges {
|
||||
console.warn('Missing drilldown configuration for level:', this.currentDrilldownLevel);
|
||||
this.noDataAvailable = true;
|
||||
this.bubbleChartData = [];
|
||||
this.dataLoaded = true;
|
||||
setTimeout(() => {
|
||||
this.forceChartUpdate();
|
||||
}, 100);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -758,35 +1053,84 @@ export class BubbleChartComponent implements OnInit, OnChanges {
|
||||
this.dashboardService.getChartData(actualApiUrl, 'bubble', drilldownConfig.xAxis, drilldownConfig.yAxis, this.connection, parameterField, parameterValue, filterParams).subscribe(
|
||||
(data: any) => {
|
||||
console.log('Received drilldown data:', data);
|
||||
if (data === null) {
|
||||
console.warn('Drilldown API returned null data. Check if the API endpoint is working correctly.');
|
||||
this.noDataAvailable = true;
|
||||
this.bubbleChartData = [];
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle the actual data structure returned by the API
|
||||
if (data && data.chartLabels && data.chartData) {
|
||||
// Reset chart data to empty first
|
||||
this.bubbleChartData = [];
|
||||
|
||||
if (data === null || data === undefined) {
|
||||
console.warn('Drilldown API returned null/undefined data. Check if the API endpoint is working correctly.');
|
||||
this.noDataAvailable = true;
|
||||
} else if (data && data.chartLabels && data.chartData) {
|
||||
// For bubble charts, we need to transform the data into bubble format
|
||||
this.noDataAvailable = data.chartLabels.length === 0;
|
||||
this.bubbleChartData = this.transformToBubbleData(data.chartLabels, data.chartData);
|
||||
console.log('Updated bubble chart with drilldown data:', this.bubbleChartData);
|
||||
const transformedData = this.transformToBubbleData(data.chartLabels, data.chartData);
|
||||
|
||||
// Check if we have valid data
|
||||
let hasValidData = false;
|
||||
if (transformedData && transformedData.length > 0) {
|
||||
for (const dataset of transformedData) {
|
||||
if (dataset.data && dataset.data.length > 0) {
|
||||
hasValidData = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasValidData) {
|
||||
this.bubbleChartData = transformedData;
|
||||
this.noDataAvailable = false;
|
||||
console.log('Updated bubble chart with drilldown data:', this.bubbleChartData);
|
||||
} else {
|
||||
console.log('No valid data after transformation in drilldown');
|
||||
this.noDataAvailable = true;
|
||||
}
|
||||
} else if (data && data.labels && data.datasets) {
|
||||
// Handle the original expected format as fallback
|
||||
this.noDataAvailable = data.labels.length === 0;
|
||||
this.bubbleChartData = data.datasets;
|
||||
console.log('Updated bubble chart with drilldown legacy data format:', this.bubbleChartData);
|
||||
// Check if we have valid data
|
||||
let hasValidData = false;
|
||||
if (data.datasets && data.datasets.length > 0) {
|
||||
for (const dataset of data.datasets) {
|
||||
if (dataset.data && dataset.data.length > 0) {
|
||||
hasValidData = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasValidData) {
|
||||
this.bubbleChartData = data.datasets;
|
||||
this.noDataAvailable = false;
|
||||
console.log('Updated bubble chart with drilldown legacy data format:', this.bubbleChartData);
|
||||
} else {
|
||||
console.log('No valid data in legacy format in drilldown');
|
||||
this.noDataAvailable = true;
|
||||
}
|
||||
} else {
|
||||
console.warn('Drilldown received data does not have expected structure', data);
|
||||
this.noDataAvailable = true;
|
||||
this.bubbleChartData = [];
|
||||
}
|
||||
|
||||
this.dataLoaded = true; // Mark data as loaded
|
||||
|
||||
console.log('Final state after drilldown data fetch:', {
|
||||
noDataAvailable: this.noDataAvailable,
|
||||
dataLoaded: this.dataLoaded,
|
||||
bubbleChartDataLength: this.bubbleChartData.length,
|
||||
isChartDataValid: this.isChartDataValid()
|
||||
});
|
||||
|
||||
// Trigger change detection
|
||||
setTimeout(() => {
|
||||
this.forceChartUpdate();
|
||||
}, 100);
|
||||
},
|
||||
(error) => {
|
||||
console.error('Error fetching drilldown data:', error);
|
||||
this.noDataAvailable = true;
|
||||
this.bubbleChartData = [];
|
||||
// Keep current data in case of error
|
||||
this.dataLoaded = true;
|
||||
setTimeout(() => {
|
||||
this.forceChartUpdate();
|
||||
}, 100);
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -933,4 +1277,52 @@ export class BubbleChartComponent implements OnInit, OnChanges {
|
||||
public chartHovered(e: any): void {
|
||||
console.log('Bubble chart hovered:', e);
|
||||
}
|
||||
|
||||
// Method to check if chart data is valid
|
||||
public isChartDataValid(): boolean {
|
||||
console.log('Checking if chart data is valid:', this.bubbleChartData);
|
||||
if (!this.bubbleChartData || this.bubbleChartData.length === 0) {
|
||||
console.log('Chart data is null or empty');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if any dataset has data
|
||||
for (const dataset of this.bubbleChartData) {
|
||||
console.log('Checking dataset:', dataset);
|
||||
if (dataset.data && dataset.data.length > 0) {
|
||||
console.log('Dataset has data, length:', dataset.data.length);
|
||||
// For bubble charts, check if data points have x, y, r properties
|
||||
for (const point of dataset.data) {
|
||||
console.log('Checking point:', point);
|
||||
if (typeof point === 'object' && point.hasOwnProperty('x') && point.hasOwnProperty('y') && point.hasOwnProperty('r')) {
|
||||
// Valid bubble point
|
||||
console.log('Found valid bubble point');
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log('No valid chart data found');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Method to force chart update
|
||||
private forceChartUpdate(): void {
|
||||
console.log('Forcing chart update');
|
||||
console.log('Current bubbleChartData:', this.bubbleChartData);
|
||||
console.log('Current bubbleChartData length:', this.bubbleChartData ? this.bubbleChartData.length : 0);
|
||||
if (this.bubbleChartData && this.bubbleChartData.length > 0) {
|
||||
console.log('First dataset data length:', this.bubbleChartData[0].data ? this.bubbleChartData[0].data.length : 0);
|
||||
}
|
||||
// Create a new reference to trigger change detection
|
||||
if (this.bubbleChartData) {
|
||||
this.bubbleChartData = [...this.bubbleChartData];
|
||||
}
|
||||
// Also update noDataAvailable to trigger UI changes
|
||||
this.noDataAvailable = this.noDataAvailable;
|
||||
console.log('Chart update forced, noDataAvailable:', this.noDataAvailable);
|
||||
console.log('Chart update forced, bubbleChartData length:', this.bubbleChartData ? this.bubbleChartData.length : 0);
|
||||
console.log('Chart update forced, isChartDataValid:', this.isChartDataValid());
|
||||
}
|
||||
}
|
||||
@@ -284,13 +284,12 @@
|
||||
<div class="chart-wrapper">
|
||||
<div class="chart-content" [class.loading]="isLoading">
|
||||
<!-- Show no data message -->
|
||||
<div class="no-data-message" *ngIf="noDataAvailable">
|
||||
<div class="no-data-message" *ngIf="noDataAvailable && doughnutChartLabels.length === 0">
|
||||
<p>No chart data available</p>
|
||||
</div>
|
||||
|
||||
<!-- Show chart when data is available -->
|
||||
<canvas baseChart
|
||||
*ngIf="!noDataAvailable && doughnutChartLabels.length > 0 && doughnutChartData.length > 0"
|
||||
[datasets]="doughnutChartData"
|
||||
[labels]="doughnutChartLabels"
|
||||
[type]="doughnutChartType"
|
||||
@@ -306,7 +305,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="chart-legend" *ngIf="!noDataAvailable && showlabel && doughnutChartLabels && doughnutChartLabels.length > 0">
|
||||
<div class="chart-legend" *ngIf="showlabel && doughnutChartLabels && doughnutChartLabels.length > 0">
|
||||
<div class="legend-item" *ngFor="let label of doughnutChartLabels; let i = index">
|
||||
<span class="legend-color" [style.background-color]="getLegendColor(i)"></span>
|
||||
<span class="legend-label">{{ label }}</span>
|
||||
|
||||
@@ -148,7 +148,10 @@ export class DoughnutChartComponent implements OnInit, OnChanges, AfterViewCheck
|
||||
|
||||
// Validate initial data
|
||||
this.validateChartData();
|
||||
this.fetchChartData();
|
||||
// Only fetch data if we have the required inputs, otherwise show default data
|
||||
if (this.table && this.xAxis && this.yAxis) {
|
||||
this.fetchChartData();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -237,6 +240,12 @@ export class DoughnutChartComponent implements OnInit, OnChanges, AfterViewCheck
|
||||
console.log('Chart configuration changed, fetching new data');
|
||||
this.fetchChartData();
|
||||
}
|
||||
|
||||
// If we have the required inputs and haven't fetched data yet, fetch it
|
||||
if ((xAxisChanged || yAxisChanged || tableChanged) && this.table && this.xAxis && this.yAxis && !this.isFetchingData) {
|
||||
console.log('Required inputs available, fetching data');
|
||||
this.fetchChartData();
|
||||
}
|
||||
}
|
||||
|
||||
ngAfterViewChecked() {
|
||||
@@ -674,11 +683,31 @@ export class DoughnutChartComponent implements OnInit, OnChanges, AfterViewCheck
|
||||
// Backend has already filtered the data, just display it
|
||||
this.noDataAvailable = data.chartLabels.length === 0;
|
||||
this.doughnutChartLabels = data.chartLabels;
|
||||
|
||||
// Handle different data structures
|
||||
let chartDataValues;
|
||||
if (Array.isArray(data.chartData)) {
|
||||
// If chartData is already an array of values
|
||||
if (data.chartData.length > 0 && typeof data.chartData[0] !== 'object') {
|
||||
chartDataValues = data.chartData;
|
||||
}
|
||||
// If chartData is an array with one object containing the data
|
||||
else if (data.chartData.length > 0 && data.chartData[0].data) {
|
||||
chartDataValues = data.chartData[0].data;
|
||||
}
|
||||
// Default case
|
||||
else {
|
||||
chartDataValues = data.chartData;
|
||||
}
|
||||
} else {
|
||||
chartDataValues = [data.chartData];
|
||||
}
|
||||
|
||||
this.doughnutChartData = [
|
||||
{
|
||||
data: data.chartData,
|
||||
backgroundColor: this.chartColors.slice(0, data.chartData.length),
|
||||
hoverBackgroundColor: this.chartColors.slice(0, data.chartData.length)
|
||||
data: chartDataValues,
|
||||
backgroundColor: this.chartColors.slice(0, chartDataValues.length),
|
||||
hoverBackgroundColor: this.chartColors.slice(0, chartDataValues.length)
|
||||
}
|
||||
];
|
||||
console.log('Updated doughnut chart with data:', { labels: this.doughnutChartLabels, data: this.doughnutChartData });
|
||||
@@ -691,12 +720,21 @@ export class DoughnutChartComponent implements OnInit, OnChanges, AfterViewCheck
|
||||
} else {
|
||||
console.warn('Received data does not have expected structure', data);
|
||||
this.noDataAvailable = true;
|
||||
this.doughnutChartLabels = [];
|
||||
// Keep default data instead of empty arrays
|
||||
this.doughnutChartLabels = ["Category A", "Category B", "Category C"];
|
||||
this.doughnutChartData = [
|
||||
{
|
||||
data: [],
|
||||
backgroundColor: [],
|
||||
hoverBackgroundColor: []
|
||||
data: [30, 50, 20],
|
||||
backgroundColor: [
|
||||
'#FF6384',
|
||||
'#36A2EB',
|
||||
'#FFCE56'
|
||||
],
|
||||
hoverBackgroundColor: [
|
||||
'#FF6384',
|
||||
'#36A2EB',
|
||||
'#FFCE56'
|
||||
]
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -707,12 +745,26 @@ export class DoughnutChartComponent implements OnInit, OnChanges, AfterViewCheck
|
||||
(error) => {
|
||||
console.error('Error fetching doughnut chart data:', error);
|
||||
this.noDataAvailable = true;
|
||||
this.doughnutChartLabels = [];
|
||||
this.doughnutChartData = [];
|
||||
// Keep default data in case of error
|
||||
this.doughnutChartLabels = ["Category A", "Category B", "Category C"];
|
||||
this.doughnutChartData = [
|
||||
{
|
||||
data: [30, 50, 20],
|
||||
backgroundColor: [
|
||||
'#FF6384',
|
||||
'#36A2EB',
|
||||
'#FFCE56'
|
||||
],
|
||||
hoverBackgroundColor: [
|
||||
'#FF6384',
|
||||
'#36A2EB',
|
||||
'#FFCE56'
|
||||
]
|
||||
}
|
||||
];
|
||||
// Reset flags after fetching
|
||||
this.isFetchingData = false;
|
||||
this.isLoading = false;
|
||||
// Keep default data in case of error
|
||||
}
|
||||
);
|
||||
} else {
|
||||
@@ -869,11 +921,31 @@ export class DoughnutChartComponent implements OnInit, OnChanges, AfterViewCheck
|
||||
// Backend has already filtered the data, just display it
|
||||
this.noDataAvailable = data.chartLabels.length === 0;
|
||||
this.doughnutChartLabels = data.chartLabels;
|
||||
|
||||
// Handle different data structures
|
||||
let chartDataValues;
|
||||
if (Array.isArray(data.chartData)) {
|
||||
// If chartData is already an array of values
|
||||
if (data.chartData.length > 0 && typeof data.chartData[0] !== 'object') {
|
||||
chartDataValues = data.chartData;
|
||||
}
|
||||
// If chartData is an array with one object containing the data
|
||||
else if (data.chartData.length > 0 && data.chartData[0].data) {
|
||||
chartDataValues = data.chartData[0].data;
|
||||
}
|
||||
// Default case
|
||||
else {
|
||||
chartDataValues = data.chartData;
|
||||
}
|
||||
} else {
|
||||
chartDataValues = [data.chartData];
|
||||
}
|
||||
|
||||
this.doughnutChartData = [
|
||||
{
|
||||
data: data.chartData,
|
||||
backgroundColor: this.chartColors.slice(0, data.chartData.length),
|
||||
hoverBackgroundColor: this.chartColors.slice(0, data.chartData.length)
|
||||
data: chartDataValues,
|
||||
backgroundColor: this.chartColors.slice(0, chartDataValues.length),
|
||||
hoverBackgroundColor: this.chartColors.slice(0, chartDataValues.length)
|
||||
}
|
||||
];
|
||||
console.log('Updated doughnut chart with drilldown data:', { labels: this.doughnutChartLabels, data: this.doughnutChartData });
|
||||
@@ -890,14 +962,7 @@ export class DoughnutChartComponent implements OnInit, OnChanges, AfterViewCheck
|
||||
} else {
|
||||
console.warn('Drilldown received data does not have expected structure', data);
|
||||
this.noDataAvailable = true;
|
||||
this.doughnutChartLabels = [];
|
||||
this.doughnutChartData = [
|
||||
{
|
||||
data: [],
|
||||
backgroundColor: [],
|
||||
hoverBackgroundColor: []
|
||||
}
|
||||
];
|
||||
// Keep current data instead of empty arrays
|
||||
// Set loading state to false
|
||||
this.isLoading = false;
|
||||
}
|
||||
@@ -905,11 +970,9 @@ export class DoughnutChartComponent implements OnInit, OnChanges, AfterViewCheck
|
||||
(error) => {
|
||||
console.error('Error fetching drilldown data:', error);
|
||||
this.noDataAvailable = true;
|
||||
this.doughnutChartLabels = [];
|
||||
this.doughnutChartData = [];
|
||||
// Keep current data in case of error
|
||||
// Set loading state to false
|
||||
this.isLoading = false;
|
||||
// Keep current data in case of error
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -281,7 +281,7 @@
|
||||
|
||||
<div class="chart-wrapper">
|
||||
<!-- Show loading indicator -->
|
||||
<div class="loading-indicator" *ngIf="pieChartLabels.length === 0 && pieChartData.length === 0 && !noDataAvailable">
|
||||
<div class="loading-indicator" *ngIf="pieChartLabels.length === 0 && pieChartData.length === 0 && !noDataAvailable && !isFetchingData">
|
||||
<div class="spinner"></div>
|
||||
<p>Loading chart data...</p>
|
||||
</div>
|
||||
@@ -291,15 +291,15 @@
|
||||
<p>No chart data available</p>
|
||||
</div>
|
||||
|
||||
<!-- Show chart when data is available -->
|
||||
<!-- Show chart when data is available or show default data -->
|
||||
<canvas baseChart
|
||||
*ngIf="pieChartLabels.length > 0 && pieChartData.length > 0"
|
||||
[data]="pieChartData"
|
||||
[datasets]="pieChartDatasets"
|
||||
[labels]="pieChartLabels"
|
||||
[type]="pieChartType"
|
||||
[options]="pieChartOptions"
|
||||
(chartHover)="chartHovered($event)"
|
||||
(chartClick)="chartClicked($event)">
|
||||
(chartClick)="chartClicked($event)"
|
||||
[style.display]="shouldShowChart() ? 'block' : 'none'">
|
||||
</canvas>
|
||||
</div>
|
||||
<div class="chart-legend" *ngIf="showlabel && pieChartLabels && pieChartLabels.length > 0">
|
||||
|
||||
@@ -37,6 +37,12 @@ export class PieChartComponent implements OnInit, OnChanges, AfterViewChecked, O
|
||||
|
||||
public pieChartLabels: string[] = ['Category A', 'Category B', 'Category C'];
|
||||
public pieChartData: number[] = [30, 50, 20];
|
||||
public pieChartDatasets: any[] = [
|
||||
{
|
||||
data: [30, 50, 20],
|
||||
label: 'Dataset 1'
|
||||
}
|
||||
];
|
||||
public pieChartType: string = 'pie';
|
||||
public pieChartOptions: any = {
|
||||
responsive: true,
|
||||
@@ -96,7 +102,7 @@ export class PieChartComponent implements OnInit, OnChanges, AfterViewChecked, O
|
||||
noDataAvailable: boolean = false;
|
||||
|
||||
// Flag to prevent infinite loops
|
||||
private isFetchingData: boolean = false;
|
||||
isFetchingData: boolean = false;
|
||||
|
||||
// Subscriptions to unsubscribe on destroy
|
||||
private subscriptions: Subscription[] = [];
|
||||
@@ -132,7 +138,17 @@ export class PieChartComponent implements OnInit, OnChanges, AfterViewChecked, O
|
||||
console.log('PieChartComponent initialized with default data:', { labels: this.pieChartLabels, data: this.pieChartData });
|
||||
// Validate initial data
|
||||
this.validateChartData();
|
||||
this.fetchChartData();
|
||||
// Initialize datasets with default data
|
||||
this.pieChartDatasets = [
|
||||
{
|
||||
data: this.pieChartData,
|
||||
label: 'Dataset 1'
|
||||
}
|
||||
];
|
||||
// Only fetch data if we have the required inputs, otherwise show default data
|
||||
if (this.table && this.xAxis && this.yAxis) {
|
||||
this.fetchChartData();
|
||||
}
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
@@ -165,6 +181,12 @@ export class PieChartComponent implements OnInit, OnChanges, AfterViewChecked, O
|
||||
console.log('Chart configuration changed, fetching new data');
|
||||
this.fetchChartData();
|
||||
}
|
||||
|
||||
// If we have the required inputs and haven't fetched data yet, fetch it
|
||||
if ((xAxisChanged || yAxisChanged || tableChanged) && this.table && this.xAxis && this.yAxis && !this.isFetchingData) {
|
||||
console.log('Required inputs available, fetching data');
|
||||
this.fetchChartData();
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
@@ -576,8 +598,6 @@ export class PieChartComponent implements OnInit, OnChanges, AfterViewChecked, O
|
||||
if (data === null) {
|
||||
console.warn('API returned null data. Check if the API endpoint is working correctly.');
|
||||
this.noDataAvailable = true;
|
||||
this.pieChartLabels = [];
|
||||
this.pieChartData = [];
|
||||
// Reset flag after fetching
|
||||
this.isFetchingData = false;
|
||||
return;
|
||||
@@ -588,9 +608,24 @@ export class PieChartComponent implements OnInit, OnChanges, AfterViewChecked, O
|
||||
// Backend has already filtered the data, just display it
|
||||
this.noDataAvailable = data.chartLabels.length === 0;
|
||||
this.pieChartLabels = data.chartLabels;
|
||||
this.pieChartData = data.chartData;
|
||||
|
||||
// Extract the actual data values from the chartData array
|
||||
// chartData is an array with one object containing the data
|
||||
if (data.chartData.length > 0 && data.chartData[0].data) {
|
||||
this.pieChartData = data.chartData[0].data;
|
||||
} else {
|
||||
this.pieChartData = [];
|
||||
}
|
||||
|
||||
// Trigger change detection
|
||||
this.pieChartLabels = [...this.pieChartLabels];
|
||||
this.pieChartData = [...this.pieChartData];
|
||||
this.pieChartDatasets = [
|
||||
{
|
||||
data: this.pieChartData,
|
||||
label: 'Dataset 1'
|
||||
}
|
||||
];
|
||||
console.log('Updated pie chart with data:', { labels: this.pieChartLabels, data: this.pieChartData });
|
||||
} else if (data && data.labels && data.datasets) {
|
||||
// Backend has already filtered the data, just display it
|
||||
@@ -598,13 +633,29 @@ export class PieChartComponent implements OnInit, OnChanges, AfterViewChecked, O
|
||||
this.pieChartLabels = data.labels;
|
||||
this.pieChartData = data.datasets[0]?.data || [];
|
||||
// Trigger change detection
|
||||
this.pieChartLabels = [...this.pieChartLabels];
|
||||
this.pieChartData = [...this.pieChartData];
|
||||
this.pieChartDatasets = [
|
||||
{
|
||||
data: this.pieChartData,
|
||||
label: 'Dataset 1'
|
||||
}
|
||||
];
|
||||
console.log('Updated pie chart with legacy data format:', { labels: this.pieChartLabels, data: this.pieChartData });
|
||||
} else {
|
||||
console.warn('Received data does not have expected structure', data);
|
||||
this.noDataAvailable = true;
|
||||
this.pieChartLabels = [];
|
||||
this.pieChartData = [];
|
||||
// Keep default data if no data is available
|
||||
if (this.pieChartLabels.length === 0 && this.pieChartData.length === 0) {
|
||||
this.pieChartLabels = ['Category A', 'Category B', 'Category C'];
|
||||
this.pieChartData = [30, 50, 20];
|
||||
this.pieChartDatasets = [
|
||||
{
|
||||
data: this.pieChartData,
|
||||
label: 'Dataset 1'
|
||||
}
|
||||
];
|
||||
}
|
||||
}
|
||||
// Reset flag after fetching
|
||||
this.isFetchingData = false;
|
||||
@@ -612,18 +663,13 @@ export class PieChartComponent implements OnInit, OnChanges, AfterViewChecked, O
|
||||
(error) => {
|
||||
console.error('Error fetching pie chart data:', error);
|
||||
this.noDataAvailable = true;
|
||||
this.pieChartLabels = [];
|
||||
this.pieChartData = [];
|
||||
// Reset flag after fetching
|
||||
this.isFetchingData = false;
|
||||
// Keep default data in case of error
|
||||
}
|
||||
);
|
||||
} else {
|
||||
console.log('Missing required data for chart:', { table: this.table, xAxis: this.xAxis, yAxis: this.yAxis, connection: this.connection });
|
||||
this.noDataAvailable = true;
|
||||
this.pieChartLabels = [];
|
||||
this.pieChartData = [];
|
||||
// Reset flag after fetching
|
||||
this.isFetchingData = false;
|
||||
}
|
||||
@@ -652,8 +698,6 @@ export class PieChartComponent implements OnInit, OnChanges, AfterViewChecked, O
|
||||
} else {
|
||||
console.warn('Invalid drilldown layer index:', layerIndex);
|
||||
this.noDataAvailable = true;
|
||||
this.pieChartLabels = [];
|
||||
this.pieChartData = [];
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -664,8 +708,6 @@ export class PieChartComponent implements OnInit, OnChanges, AfterViewChecked, O
|
||||
if (!drilldownConfig || !drilldownConfig.apiUrl || !drilldownConfig.xAxis || !drilldownConfig.yAxis) {
|
||||
console.warn('Missing drilldown configuration for level:', this.currentDrilldownLevel);
|
||||
this.noDataAvailable = true;
|
||||
this.pieChartLabels = [];
|
||||
this.pieChartData = [];
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -762,8 +804,6 @@ export class PieChartComponent implements OnInit, OnChanges, AfterViewChecked, O
|
||||
if (data === null) {
|
||||
console.warn('Drilldown API returned null data. Check if the API endpoint is working correctly.');
|
||||
this.noDataAvailable = true;
|
||||
this.pieChartLabels = [];
|
||||
this.pieChartData = [];
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -772,9 +812,24 @@ export class PieChartComponent implements OnInit, OnChanges, AfterViewChecked, O
|
||||
// Backend has already filtered the data, just display it
|
||||
this.noDataAvailable = data.chartLabels.length === 0;
|
||||
this.pieChartLabels = data.chartLabels;
|
||||
this.pieChartData = data.chartData;
|
||||
|
||||
// Extract the actual data values from the chartData array
|
||||
// chartData is an array with one object containing the data
|
||||
if (data.chartData.length > 0 && data.chartData[0].data) {
|
||||
this.pieChartData = data.chartData[0].data;
|
||||
} else {
|
||||
this.pieChartData = [];
|
||||
}
|
||||
|
||||
// Trigger change detection
|
||||
this.pieChartLabels = [...this.pieChartLabels];
|
||||
this.pieChartData = [...this.pieChartData];
|
||||
this.pieChartDatasets = [
|
||||
{
|
||||
data: this.pieChartData,
|
||||
label: 'Dataset 1'
|
||||
}
|
||||
];
|
||||
console.log('Updated pie chart with drilldown data:', { labels: this.pieChartLabels, data: this.pieChartData });
|
||||
} else if (data && data.labels && data.datasets) {
|
||||
// Backend has already filtered the data, just display it
|
||||
@@ -782,21 +837,24 @@ export class PieChartComponent implements OnInit, OnChanges, AfterViewChecked, O
|
||||
this.pieChartLabels = data.labels;
|
||||
this.pieChartData = data.datasets[0]?.data || [];
|
||||
// Trigger change detection
|
||||
this.pieChartLabels = [...this.pieChartLabels];
|
||||
this.pieChartData = [...this.pieChartData];
|
||||
this.pieChartDatasets = [
|
||||
{
|
||||
data: this.pieChartData,
|
||||
label: 'Dataset 1'
|
||||
}
|
||||
];
|
||||
console.log('Updated pie chart with drilldown legacy data format:', { labels: this.pieChartLabels, data: this.pieChartData });
|
||||
} else {
|
||||
console.warn('Drilldown received data does not have expected structure', data);
|
||||
this.noDataAvailable = true;
|
||||
this.pieChartLabels = [];
|
||||
this.pieChartData = [];
|
||||
// Keep current data if no data is available
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
console.error('Error fetching drilldown data:', error);
|
||||
this.noDataAvailable = true;
|
||||
this.pieChartLabels = [];
|
||||
this.pieChartData = [];
|
||||
// Keep current data in case of error
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -885,6 +943,26 @@ export class PieChartComponent implements OnInit, OnChanges, AfterViewChecked, O
|
||||
return this.chartColors[index % this.chartColors.length];
|
||||
}
|
||||
|
||||
// Method to determine if chart should be displayed
|
||||
shouldShowChart(): boolean {
|
||||
// Show chart if we have data
|
||||
if (this.pieChartLabels.length > 0 && this.pieChartData.length > 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Show chart if we're still fetching data
|
||||
if (this.isFetchingData) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Show chart if we have default data
|
||||
if (this.pieChartLabels.length > 0 && this.originalPieChartLabels.length > 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// events
|
||||
public chartClicked(e: any): void {
|
||||
console.log('Pie chart clicked:', e);
|
||||
|
||||
@@ -279,10 +279,11 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="position: relative; height: calc(100% - 50px);">
|
||||
<div style="position: relative; height: calc(100% - 80px); padding: 0 10px 30px 10px;">
|
||||
<canvas baseChart
|
||||
[datasets]="polarAreaChartData"
|
||||
[labels]="polarAreaChartLabels"
|
||||
[options]="polarAreaChartOptions"
|
||||
[type]="polarAreaChartType"
|
||||
(chartHover)="chartHovered($event)"
|
||||
(chartClick)="chartClicked($event)">
|
||||
|
||||
@@ -90,6 +90,32 @@ export class PolarChartComponent implements OnInit, OnChanges {
|
||||
{ data: [ 300, 500, 100, 40, 120 ], label: 'Series 1'}
|
||||
];
|
||||
|
||||
public polarAreaChartOptions: any = {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
layout: {
|
||||
padding: {
|
||||
left: 10,
|
||||
right: 10,
|
||||
top: 10,
|
||||
bottom: 30
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
legend: {
|
||||
display: true,
|
||||
position: 'top'
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
r: {
|
||||
ticks: {
|
||||
backdropColor: 'rgba(0, 0, 0, 0)'
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public polarAreaChartType: string = 'polarArea';
|
||||
|
||||
// Multi-layer drilldown state tracking
|
||||
@@ -511,7 +537,12 @@ export class PolarChartComponent implements OnInit, OnChanges {
|
||||
console.warn('Polar chart API returned null data. Check if the API endpoint is working correctly.');
|
||||
this.noDataAvailable = true;
|
||||
this.polarAreaChartLabels = [];
|
||||
this.polarAreaChartData = [];
|
||||
this.polarAreaChartData = [
|
||||
{
|
||||
data: [],
|
||||
label: 'Dataset 1'
|
||||
}
|
||||
];
|
||||
// Reset flag after fetching
|
||||
this.isFetchingData = false;
|
||||
return;
|
||||
@@ -524,32 +555,54 @@ export class PolarChartComponent implements OnInit, OnChanges {
|
||||
this.noDataAvailable = data.chartLabels.length === 0;
|
||||
this.polarAreaChartLabels = data.chartLabels;
|
||||
if (data.chartData && data.chartData.length > 0) {
|
||||
this.polarAreaChartData = data.chartData[0].data.map(value => {
|
||||
// Convert the data to the expected format for polar area charts
|
||||
const chartValues = data.chartData[0].data.map(value => {
|
||||
// Convert to number if it's not already
|
||||
return isNaN(Number(value)) ? 0 : Number(value);
|
||||
});
|
||||
// Assign data in the correct format (array of objects with data property)
|
||||
this.polarAreaChartData = [
|
||||
{
|
||||
data: chartValues,
|
||||
label: data.chartData[0].label || 'Dataset 1'
|
||||
}
|
||||
];
|
||||
} else {
|
||||
this.polarAreaChartData = [];
|
||||
this.polarAreaChartData = [
|
||||
{
|
||||
data: [],
|
||||
label: 'Dataset 1'
|
||||
}
|
||||
];
|
||||
}
|
||||
// Trigger change detection
|
||||
this.polarAreaChartData = [...this.polarAreaChartData];
|
||||
console.log('Updated polar chart with data:', { labels: this.polarAreaChartLabels, data: this.polarAreaChartData });
|
||||
} else if (data && data.labels && data.data) {
|
||||
// Handle the original expected format as fallback
|
||||
this.noDataAvailable = data.labels.length === 0;
|
||||
this.polarAreaChartLabels = data.labels;
|
||||
this.polarAreaChartData = data.data.map(value => {
|
||||
// Convert the data to the expected format for polar area charts
|
||||
const chartValues = data.data.map(value => {
|
||||
// Convert to number if it's not already
|
||||
return isNaN(Number(value)) ? 0 : Number(value);
|
||||
});
|
||||
// Trigger change detection
|
||||
this.polarAreaChartData = [...this.polarAreaChartData];
|
||||
// Assign data in the correct format (array of objects with data property)
|
||||
this.polarAreaChartData = [
|
||||
{
|
||||
data: chartValues,
|
||||
label: 'Dataset 1'
|
||||
}
|
||||
];
|
||||
console.log('Updated polar chart with legacy data format:', { labels: this.polarAreaChartLabels, data: this.polarAreaChartData });
|
||||
} else {
|
||||
console.warn('Polar chart received data does not have expected structure', data);
|
||||
this.noDataAvailable = true;
|
||||
this.polarAreaChartLabels = [];
|
||||
this.polarAreaChartData = [];
|
||||
this.polarAreaChartData = [
|
||||
{
|
||||
data: [],
|
||||
label: 'Dataset 1'
|
||||
}
|
||||
];
|
||||
}
|
||||
// Reset flag after fetching
|
||||
this.isFetchingData = false;
|
||||
@@ -558,7 +611,12 @@ export class PolarChartComponent implements OnInit, OnChanges {
|
||||
console.error('Error fetching polar chart data:', error);
|
||||
this.noDataAvailable = true;
|
||||
this.polarAreaChartLabels = [];
|
||||
this.polarAreaChartData = [];
|
||||
this.polarAreaChartData = [
|
||||
{
|
||||
data: [],
|
||||
label: 'Dataset 1'
|
||||
}
|
||||
];
|
||||
// Reset flag after fetching
|
||||
this.isFetchingData = false;
|
||||
// Keep default data in case of error
|
||||
@@ -568,7 +626,12 @@ export class PolarChartComponent implements OnInit, OnChanges {
|
||||
console.log('Missing required data for polar chart:', { table: this.table, xAxis: this.xAxis, yAxis: this.yAxis, connection: this.connection });
|
||||
this.noDataAvailable = true;
|
||||
this.polarAreaChartLabels = [];
|
||||
this.polarAreaChartData = [];
|
||||
this.polarAreaChartData = [
|
||||
{
|
||||
data: [],
|
||||
label: 'Dataset 1'
|
||||
}
|
||||
];
|
||||
// Reset flag after fetching
|
||||
this.isFetchingData = false;
|
||||
}
|
||||
@@ -598,7 +661,12 @@ export class PolarChartComponent implements OnInit, OnChanges {
|
||||
console.warn('Invalid drilldown layer index:', layerIndex);
|
||||
this.noDataAvailable = true;
|
||||
this.polarAreaChartLabels = [];
|
||||
this.polarAreaChartData = [];
|
||||
this.polarAreaChartData = [
|
||||
{
|
||||
data: [],
|
||||
label: 'Dataset 1'
|
||||
}
|
||||
];
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -610,7 +678,12 @@ export class PolarChartComponent implements OnInit, OnChanges {
|
||||
console.warn('Missing drilldown configuration for level:', this.currentDrilldownLevel);
|
||||
this.noDataAvailable = true;
|
||||
this.polarAreaChartLabels = [];
|
||||
this.polarAreaChartData = [];
|
||||
this.polarAreaChartData = [
|
||||
{
|
||||
data: [],
|
||||
label: 'Dataset 1'
|
||||
}
|
||||
];
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -708,7 +781,12 @@ export class PolarChartComponent implements OnInit, OnChanges {
|
||||
console.warn('Drilldown API returned null data. Check if the API endpoint is working correctly.');
|
||||
this.noDataAvailable = true;
|
||||
this.polarAreaChartLabels = [];
|
||||
this.polarAreaChartData = [];
|
||||
this.polarAreaChartData = [
|
||||
{
|
||||
data: [],
|
||||
label: 'Dataset 1'
|
||||
}
|
||||
];
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -718,12 +796,25 @@ export class PolarChartComponent implements OnInit, OnChanges {
|
||||
this.noDataAvailable = data.chartLabels.length === 0;
|
||||
this.polarAreaChartLabels = data.chartLabels;
|
||||
if (data.chartData && data.chartData.length > 0) {
|
||||
this.polarAreaChartData = data.chartData[0].data.map(value => {
|
||||
// Convert the data to the expected format for polar area charts
|
||||
const chartValues = data.chartData[0].data.map(value => {
|
||||
// Convert to number if it's not already
|
||||
return isNaN(Number(value)) ? 0 : Number(value);
|
||||
});
|
||||
// Assign data in the correct format (array of objects with data property)
|
||||
this.polarAreaChartData = [
|
||||
{
|
||||
data: chartValues,
|
||||
label: data.chartData[0].label || 'Dataset 1'
|
||||
}
|
||||
];
|
||||
} else {
|
||||
this.polarAreaChartData = [];
|
||||
this.polarAreaChartData = [
|
||||
{
|
||||
data: [],
|
||||
label: 'Dataset 1'
|
||||
}
|
||||
];
|
||||
}
|
||||
// Trigger change detection
|
||||
this.polarAreaChartData = [...this.polarAreaChartData];
|
||||
@@ -732,10 +823,18 @@ export class PolarChartComponent implements OnInit, OnChanges {
|
||||
// Handle the original expected format as fallback
|
||||
this.noDataAvailable = data.labels.length === 0;
|
||||
this.polarAreaChartLabels = data.labels;
|
||||
this.polarAreaChartData = data.data.map(value => {
|
||||
// Convert the data to the expected format for polar area charts
|
||||
const chartValues = data.data.map(value => {
|
||||
// Convert to number if it's not already
|
||||
return isNaN(Number(value)) ? 0 : Number(value);
|
||||
});
|
||||
// Assign data in the correct format (array of objects with data property)
|
||||
this.polarAreaChartData = [
|
||||
{
|
||||
data: chartValues,
|
||||
label: 'Dataset 1'
|
||||
}
|
||||
];
|
||||
// Trigger change detection
|
||||
this.polarAreaChartData = [...this.polarAreaChartData];
|
||||
console.log('Updated polar chart with drilldown legacy data format:', { labels: this.polarAreaChartLabels, data: this.polarAreaChartData });
|
||||
@@ -743,14 +842,24 @@ export class PolarChartComponent implements OnInit, OnChanges {
|
||||
console.warn('Drilldown received data does not have expected structure', data);
|
||||
this.noDataAvailable = true;
|
||||
this.polarAreaChartLabels = [];
|
||||
this.polarAreaChartData = [];
|
||||
this.polarAreaChartData = [
|
||||
{
|
||||
data: [],
|
||||
label: 'Dataset 1'
|
||||
}
|
||||
];
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
console.error('Error fetching drilldown data:', error);
|
||||
this.noDataAvailable = true;
|
||||
this.polarAreaChartLabels = [];
|
||||
this.polarAreaChartData = [];
|
||||
this.polarAreaChartData = [
|
||||
{
|
||||
data: [],
|
||||
label: 'Dataset 1'
|
||||
}
|
||||
];
|
||||
// Keep current data in case of error
|
||||
}
|
||||
);
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export * from './unified-chart.component';
|
||||
@@ -0,0 +1,365 @@
|
||||
<div class="chart-container" *ngIf="!noDataAvailable && !isLoading">
|
||||
<!-- Back button for drilldown navigation -->
|
||||
<div class="drilldown-back" *ngIf="currentDrilldownLevel > 0">
|
||||
<button class="btn btn-sm btn-secondary" (click)="navigateBack()">
|
||||
<clr-icon shape="arrow" dir="left"></clr-icon>
|
||||
Back
|
||||
</button>
|
||||
<span class="drilldown-level">Level: {{ currentDrilldownLevel }}</span>
|
||||
</div>
|
||||
|
||||
<!-- Chart title -->
|
||||
<div class="chart-title" *ngIf="charttitle">
|
||||
<h4>{{ charttitle }}</h4>
|
||||
</div>
|
||||
|
||||
<!-- Render different chart types based on chartType input -->
|
||||
<div class="chart-wrapper">
|
||||
<!-- Bar Chart -->
|
||||
<div *ngIf="chartType === 'bar'">
|
||||
<canvas baseChart
|
||||
[data]="chartData"
|
||||
[labels]="chartLabels"
|
||||
[options]="chartOptions"
|
||||
[legend]="chartLegend"
|
||||
[chartType]="'bar'"
|
||||
(chartClick)="chartClicked($event)"
|
||||
(chartHover)="chartHovered($event)">
|
||||
</canvas>
|
||||
</div>
|
||||
|
||||
<!-- Line Chart -->
|
||||
<div *ngIf="chartType === 'line'">
|
||||
<canvas baseChart
|
||||
[data]="chartData"
|
||||
[labels]="chartLabels"
|
||||
[options]="chartOptions"
|
||||
[legend]="chartLegend"
|
||||
[chartType]="'line'"
|
||||
(chartClick)="chartClicked($event)"
|
||||
(chartHover)="chartHovered($event)">
|
||||
</canvas>
|
||||
</div>
|
||||
|
||||
<!-- Pie Chart -->
|
||||
<div *ngIf="chartType === 'pie'">
|
||||
<canvas baseChart
|
||||
[data]="chartData"
|
||||
[labels]="chartLabels"
|
||||
[options]="chartOptions"
|
||||
[legend]="chartLegend"
|
||||
[chartType]="'pie'"
|
||||
(chartClick)="chartClicked($event)"
|
||||
(chartHover)="chartHovered($event)">
|
||||
</canvas>
|
||||
</div>
|
||||
|
||||
<!-- Doughnut Chart -->
|
||||
<div *ngIf="chartType === 'doughnut'">
|
||||
<canvas baseChart
|
||||
[data]="chartData"
|
||||
[labels]="chartLabels"
|
||||
[options]="chartOptions"
|
||||
[legend]="chartLegend"
|
||||
[chartType]="'doughnut'"
|
||||
(chartClick)="chartClicked($event)"
|
||||
(chartHover)="chartHovered($event)">
|
||||
</canvas>
|
||||
</div>
|
||||
|
||||
<!-- Bubble Chart -->
|
||||
<div *ngIf="chartType === 'bubble'">
|
||||
<canvas baseChart
|
||||
[datasets]="bubbleChartData"
|
||||
[options]="chartOptions"
|
||||
[legend]="chartLegend"
|
||||
[chartType]="'bubble'"
|
||||
(chartClick)="chartClicked($event)"
|
||||
(chartHover)="chartHovered($event)">
|
||||
</canvas>
|
||||
</div>
|
||||
|
||||
<!-- Radar Chart -->
|
||||
<div *ngIf="chartType === 'radar'">
|
||||
<canvas baseChart
|
||||
[data]="chartData"
|
||||
[labels]="chartLabels"
|
||||
[options]="chartOptions"
|
||||
[legend]="chartLegend"
|
||||
[chartType]="'radar'"
|
||||
(chartClick)="chartClicked($event)"
|
||||
(chartHover)="chartHovered($event)">
|
||||
</canvas>
|
||||
</div>
|
||||
|
||||
<!-- Polar Area Chart -->
|
||||
<div *ngIf="chartType === 'polar'">
|
||||
<canvas baseChart
|
||||
[data]="chartData"
|
||||
[labels]="chartLabels"
|
||||
[options]="chartOptions"
|
||||
[legend]="chartLegend"
|
||||
[chartType]="'polarArea'"
|
||||
(chartClick)="chartClicked($event)"
|
||||
(chartHover)="chartHovered($event)">
|
||||
</canvas>
|
||||
</div>
|
||||
|
||||
<!-- Scatter Chart -->
|
||||
<div *ngIf="chartType === 'scatter'">
|
||||
<canvas baseChart
|
||||
[datasets]="chartData"
|
||||
[options]="chartOptions"
|
||||
[legend]="chartLegend"
|
||||
[chartType]="'scatter'"
|
||||
(chartClick)="chartClicked($event)"
|
||||
(chartHover)="chartHovered($event)">
|
||||
</canvas>
|
||||
</div>
|
||||
|
||||
<!-- Default/Unknown Chart Type -->
|
||||
<div *ngIf="!['bar', 'line', 'pie', 'doughnut', 'bubble', 'radar', 'polar', 'scatter'].includes(chartType)">
|
||||
<canvas baseChart
|
||||
[data]="chartData"
|
||||
[labels]="chartLabels"
|
||||
[options]="chartOptions"
|
||||
[legend]="chartLegend"
|
||||
[chartType]="'bar'"
|
||||
(chartClick)="chartClicked($event)"
|
||||
(chartHover)="chartHovered($event)">
|
||||
</canvas>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Base Filters -->
|
||||
<div class="filters-section" *ngIf="baseFilters && baseFilters.length > 0">
|
||||
<h5>Filters</h5>
|
||||
<div class="filters-container">
|
||||
<div class="filter-item" *ngFor="let filter of baseFilters; let i = index">
|
||||
<!-- Text Filter -->
|
||||
<div *ngIf="filter.type === 'text'" class="filter-text">
|
||||
<label>{{ filter.field }}</label>
|
||||
<input type="text" [(ngModel)]="filter.value" (ngModelChange)="onBaseFilterChange(filter)"
|
||||
class="form-control" placeholder="Enter {{ filter.field }}">
|
||||
</div>
|
||||
|
||||
<!-- Dropdown Filter -->
|
||||
<div *ngIf="filter.type === 'dropdown'" class="filter-dropdown">
|
||||
<label>{{ filter.field }}</label>
|
||||
<select [(ngModel)]="filter.value" (ngModelChange)="onBaseFilterChange(filter)" class="form-control">
|
||||
<option value="">Select {{ filter.field }}</option>
|
||||
<option *ngFor="let option of getFilterOptions(filter)" [value]="option">
|
||||
{{ option }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Multiselect Filter -->
|
||||
<div *ngIf="filter.type === 'multiselect'" class="filter-multiselect">
|
||||
<label>{{ filter.field }}</label>
|
||||
<div class="multiselect-container">
|
||||
<div class="multiselect-display" (click)="toggleMultiselect(filter, 'base')">
|
||||
<span *ngIf="getSelectedOptionsCount(filter) === 0">Select {{ filter.field }}</span>
|
||||
<span *ngIf="getSelectedOptionsCount(filter) > 0">
|
||||
{{ getSelectedOptionsCount(filter) }} selected
|
||||
</span>
|
||||
</div>
|
||||
<div class="multiselect-dropdown" *ngIf="isMultiselectOpen(filter, 'base')">
|
||||
<div class="multiselect-option" *ngFor="let option of getFilterOptions(filter)">
|
||||
<input type="checkbox"
|
||||
[checked]="isOptionSelected(filter, option)"
|
||||
(change)="onMultiSelectChange(filter, option, $event)"
|
||||
id="base-{{ filter.field }}-{{ option }}">
|
||||
<label [for]="'base-' + filter.field + '-' + option">{{ option }}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Date Range Filter -->
|
||||
<div *ngIf="filter.type === 'date-range'" class="filter-date-range">
|
||||
<label>{{ filter.field }}</label>
|
||||
<div class="date-range-inputs">
|
||||
<input type="date" [(ngModel)]="filter.value.start" (ngModelChange)="onDateRangeChange(filter, filter.value)"
|
||||
class="form-control" placeholder="Start Date">
|
||||
<input type="date" [(ngModel)]="filter.value.end" (ngModelChange)="onDateRangeChange(filter, filter.value)"
|
||||
class="form-control" placeholder="End Date">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Toggle Filter -->
|
||||
<div *ngIf="filter.type === 'toggle'" class="filter-toggle">
|
||||
<label>{{ filter.field }}</label>
|
||||
<div class="toggle-switch">
|
||||
<input type="checkbox" [(ngModel)]="filter.value" (ngModelChange)="onToggleChange(filter, $event.target.checked)"
|
||||
id="toggle-{{ filter.field }}">
|
||||
<label [for]="'toggle-' + filter.field" class="toggle-label">
|
||||
<span class="toggle-slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Drilldown Filters -->
|
||||
<div class="filters-section" *ngIf="drilldownFilters && drilldownFilters.length > 0 && currentDrilldownLevel > 0">
|
||||
<h5>Drilldown Filters</h5>
|
||||
<div class="filters-container">
|
||||
<div class="filter-item" *ngFor="let filter of drilldownFilters; let i = index">
|
||||
<!-- Text Filter -->
|
||||
<div *ngIf="filter.type === 'text'" class="filter-text">
|
||||
<label>{{ filter.field }}</label>
|
||||
<input type="text" [(ngModel)]="filter.value" (ngModelChange)="onDrilldownFilterChange(filter)"
|
||||
class="form-control" placeholder="Enter {{ filter.field }}">
|
||||
</div>
|
||||
|
||||
<!-- Dropdown Filter -->
|
||||
<div *ngIf="filter.type === 'dropdown'" class="filter-dropdown">
|
||||
<label>{{ filter.field }}</label>
|
||||
<select [(ngModel)]="filter.value" (ngModelChange)="onDrilldownFilterChange(filter)" class="form-control">
|
||||
<option value="">Select {{ filter.field }}</option>
|
||||
<option *ngFor="let option of getFilterOptions(filter)" [value]="option">
|
||||
{{ option }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Multiselect Filter -->
|
||||
<div *ngIf="filter.type === 'multiselect'" class="filter-multiselect">
|
||||
<label>{{ filter.field }}</label>
|
||||
<div class="multiselect-container">
|
||||
<div class="multiselect-display" (click)="toggleMultiselect(filter, 'drilldown')">
|
||||
<span *ngIf="getSelectedOptionsCount(filter) === 0">Select {{ filter.field }}</span>
|
||||
<span *ngIf="getSelectedOptionsCount(filter) > 0">
|
||||
{{ getSelectedOptionsCount(filter) }} selected
|
||||
</span>
|
||||
</div>
|
||||
<div class="multiselect-dropdown" *ngIf="isMultiselectOpen(filter, 'drilldown')">
|
||||
<div class="multiselect-option" *ngFor="let option of getFilterOptions(filter)">
|
||||
<input type="checkbox"
|
||||
[checked]="isOptionSelected(filter, option)"
|
||||
(change)="onMultiSelectChange(filter, option, $event)"
|
||||
id="drilldown-{{ filter.field }}-{{ option }}">
|
||||
<label [for]="'drilldown-' + filter.field + '-' + option">{{ option }}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Date Range Filter -->
|
||||
<div *ngIf="filter.type === 'date-range'" class="filter-date-range">
|
||||
<label>{{ filter.field }}</label>
|
||||
<div class="date-range-inputs">
|
||||
<input type="date" [(ngModel)]="filter.value.start" (ngModelChange)="onDateRangeChange(filter, filter.value)"
|
||||
class="form-control" placeholder="Start Date">
|
||||
<input type="date" [(ngModel)]="filter.value.end" (ngModelChange)="onDateRangeChange(filter, filter.value)"
|
||||
class="form-control" placeholder="End Date">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Toggle Filter -->
|
||||
<div *ngIf="filter.type === 'toggle'" class="filter-toggle">
|
||||
<label>{{ filter.field }}</label>
|
||||
<div class="toggle-switch">
|
||||
<input type="checkbox" [(ngModel)]="filter.value" (ngModelChange)="onToggleChange(filter, $event.target.checked)"
|
||||
id="drilldown-toggle-{{ filter.field }}">
|
||||
<label [for]="'drilldown-toggle-' + filter.field" class="toggle-label">
|
||||
<span class="toggle-slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Layer Filters -->
|
||||
<div class="filters-section" *ngIf="hasActiveLayerFilters()">
|
||||
<h5>Layer Filters</h5>
|
||||
<div class="filters-container">
|
||||
<div class="filter-item" *ngFor="let filter of getActiveLayerFilters(); let i = index">
|
||||
<!-- Text Filter -->
|
||||
<div *ngIf="filter.type === 'text'" class="filter-text">
|
||||
<label>{{ filter.field }}</label>
|
||||
<input type="text" [(ngModel)]="filter.value" (ngModelChange)="onLayerFilterChange(filter)"
|
||||
class="form-control" placeholder="Enter {{ filter.field }}">
|
||||
</div>
|
||||
|
||||
<!-- Dropdown Filter -->
|
||||
<div *ngIf="filter.type === 'dropdown'" class="filter-dropdown">
|
||||
<label>{{ filter.field }}</label>
|
||||
<select [(ngModel)]="filter.value" (ngModelChange)="onLayerFilterChange(filter)" class="form-control">
|
||||
<option value="">Select {{ filter.field }}</option>
|
||||
<option *ngFor="let option of getFilterOptions(filter)" [value]="option">
|
||||
{{ option }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Multiselect Filter -->
|
||||
<div *ngIf="filter.type === 'multiselect'" class="filter-multiselect">
|
||||
<label>{{ filter.field }}</label>
|
||||
<div class="multiselect-container">
|
||||
<div class="multiselect-display" (click)="toggleMultiselect(filter, 'layer')">
|
||||
<span *ngIf="getSelectedOptionsCount(filter) === 0">Select {{ filter.field }}</span>
|
||||
<span *ngIf="getSelectedOptionsCount(filter) > 0">
|
||||
{{ getSelectedOptionsCount(filter) }} selected
|
||||
</span>
|
||||
</div>
|
||||
<div class="multiselect-dropdown" *ngIf="isMultiselectOpen(filter, 'layer')">
|
||||
<div class="multiselect-option" *ngFor="let option of getFilterOptions(filter)">
|
||||
<input type="checkbox"
|
||||
[checked]="isOptionSelected(filter, option)"
|
||||
(change)="onMultiSelectChange(filter, option, $event)"
|
||||
id="layer-{{ filter.field }}-{{ option }}">
|
||||
<label [for]="'layer-' + filter.field + '-' + option">{{ option }}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Date Range Filter -->
|
||||
<div *ngIf="filter.type === 'date-range'" class="filter-date-range">
|
||||
<label>{{ filter.field }}</label>
|
||||
<div class="date-range-inputs">
|
||||
<input type="date" [(ngModel)]="filter.value.start" (ngModelChange)="onDateRangeChange(filter, filter.value)"
|
||||
class="form-control" placeholder="Start Date">
|
||||
<input type="date" [(ngModel)]="filter.value.end" (ngModelChange)="onDateRangeChange(filter, filter.value)"
|
||||
class="form-control" placeholder="End Date">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Toggle Filter -->
|
||||
<div *ngIf="filter.type === 'toggle'" class="filter-toggle">
|
||||
<label>{{ filter.field }}</label>
|
||||
<div class="toggle-switch">
|
||||
<input type="checkbox" [(ngModel)]="filter.value" (ngModelChange)="onToggleChange(filter, $event.target.checked)"
|
||||
id="layer-toggle-{{ filter.field }}">
|
||||
<label [for]="'layer-toggle-' + filter.field" class="toggle-label">
|
||||
<span class="toggle-slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Clear Filters Button -->
|
||||
<div class="clear-filters" *ngIf="hasActiveFilters()">
|
||||
<button class="btn btn-sm btn-outline" (click)="clearAllFilters()">
|
||||
Clear All Filters
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- No Data Available Message -->
|
||||
<div class="no-data-message" *ngIf="noDataAvailable && !isLoading">
|
||||
<p>No data available for the selected filters.</p>
|
||||
<button class="btn btn-sm btn-primary" (click)="fetchChartData()">Retry</button>
|
||||
</div>
|
||||
|
||||
<!-- Loading Indicator -->
|
||||
<div class="loading-indicator" *ngIf="isLoading">
|
||||
<div class="spinner"></div>
|
||||
<p>Loading chart data...</p>
|
||||
</div>
|
||||
@@ -0,0 +1,262 @@
|
||||
.chart-container {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.drilldown-back {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 10px;
|
||||
|
||||
.drilldown-level {
|
||||
margin-left: 10px;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
|
||||
.chart-title {
|
||||
text-align: center;
|
||||
margin-bottom: 15px;
|
||||
|
||||
h4 {
|
||||
margin: 0;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.chart-wrapper {
|
||||
position: relative;
|
||||
height: calc(100% - 100px);
|
||||
min-height: 300px;
|
||||
}
|
||||
|
||||
.filters-section {
|
||||
margin-top: 20px;
|
||||
padding: 15px;
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 4px;
|
||||
background-color: #f9f9f9;
|
||||
|
||||
h5 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 10px;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.filters-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.filter-item {
|
||||
flex: 1 1 200px;
|
||||
min-width: 150px;
|
||||
|
||||
label {
|
||||
display: block;
|
||||
margin-bottom: 5px;
|
||||
font-weight: 500;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
width: 100%;
|
||||
padding: 8px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.filter-text,
|
||||
.filter-dropdown,
|
||||
.filter-date-range {
|
||||
.form-control {
|
||||
height: 36px;
|
||||
}
|
||||
}
|
||||
|
||||
.date-range-inputs {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
|
||||
.form-control {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.filter-multiselect {
|
||||
position: relative;
|
||||
|
||||
.multiselect-container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.multiselect-display {
|
||||
width: 100%;
|
||||
padding: 8px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
background-color: white;
|
||||
cursor: pointer;
|
||||
min-height: 36px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.multiselect-dropdown {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background-color: white;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||
z-index: 1000;
|
||||
max-height: 200px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.multiselect-option {
|
||||
padding: 8px 12px;
|
||||
border-bottom: 1px solid #eee;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
label {
|
||||
margin: 0;
|
||||
font-weight: normal;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.filter-toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
|
||||
.toggle-switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 50px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.toggle-switch input {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.toggle-label {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: #ccc;
|
||||
transition: .4s;
|
||||
border-radius: 24px;
|
||||
}
|
||||
|
||||
.toggle-slider {
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
left: 4px;
|
||||
bottom: 4px;
|
||||
background-color: white;
|
||||
transition: .4s;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
input:checked + .toggle-label {
|
||||
background-color: #2196F3;
|
||||
}
|
||||
|
||||
input:checked + .toggle-label .toggle-slider {
|
||||
transform: translateX(26px);
|
||||
}
|
||||
}
|
||||
|
||||
.clear-filters {
|
||||
margin-top: 15px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.no-data-message {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 300px;
|
||||
text-align: center;
|
||||
color: #666;
|
||||
|
||||
p {
|
||||
margin-bottom: 15px;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.loading-indicator {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 300px;
|
||||
|
||||
.spinner {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border: 4px solid #f3f3f3;
|
||||
border-top: 4px solid #3498db;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
// Responsive adjustments
|
||||
@media (max-width: 768px) {
|
||||
.filters-container {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.filter-item {
|
||||
min-width: 100%;
|
||||
}
|
||||
|
||||
.chart-wrapper {
|
||||
min-height: 250px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { UnifiedChartComponent } from './unified-chart.component';
|
||||
|
||||
describe('UnifiedChartComponent', () => {
|
||||
let component: UnifiedChartComponent;
|
||||
let fixture: ComponentFixture<UnifiedChartComponent>;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [UnifiedChartComponent]
|
||||
});
|
||||
fixture = TestBed.createComponent(UnifiedChartComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
File diff suppressed because it is too large
Load Diff
@@ -12,23 +12,23 @@ import { ModulesetupService } from 'src/app/services/builder/modulesetup.service
|
||||
styleUrls: ['./dashrunnerall.component.scss']
|
||||
})
|
||||
export class DashrunnerallComponent implements OnInit {
|
||||
addModall:boolean = false;
|
||||
selected:any[] = [];
|
||||
addModall: boolean = false;
|
||||
selected: any[] = [];
|
||||
loading = false;
|
||||
data:any;
|
||||
id:any;
|
||||
moduleId:any;
|
||||
data: any;
|
||||
id: any;
|
||||
moduleId: any;
|
||||
modalDelete = false;
|
||||
rowSelected :any= {};
|
||||
rowSelected: any = {};
|
||||
rows: any[];
|
||||
projectname;
|
||||
projectId;
|
||||
error;
|
||||
constructor(
|
||||
private router : Router,
|
||||
private route: ActivatedRoute,private dashboardService : Dashboard3Service,
|
||||
private router: Router,
|
||||
private route: ActivatedRoute, private dashboardService: Dashboard3Service,
|
||||
// private wireframeservice : WireframeService,
|
||||
private excel: ExcelService,private mainService: ModulesetupService,
|
||||
private excel: ExcelService, private mainService: ModulesetupService,
|
||||
private toastr: ToastrService,) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
@@ -42,41 +42,46 @@ export class DashrunnerallComponent implements OnInit {
|
||||
// this.getprojectName(this.projectId);
|
||||
}
|
||||
|
||||
getprojectName(id){
|
||||
getprojectName(id) {
|
||||
this.mainService.getProjectModules(id).subscribe((data) => {
|
||||
console.log(data);
|
||||
this.projectname=data.items[0]['projectName'];
|
||||
this.projectname = data.items[0]['projectName'];
|
||||
console.log(this.projectname);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
getdashboard()
|
||||
{
|
||||
this.dashboardService.getAllDash().subscribe((data) =>{
|
||||
getdashboard() {
|
||||
this.dashboardService.getAllDash().subscribe((data) => {
|
||||
this.data = data;
|
||||
this.rows = this.data;
|
||||
console.log(data);
|
||||
this.error="No data Available";
|
||||
this.error = "No data Available";
|
||||
console.log(this.error);
|
||||
});
|
||||
}
|
||||
|
||||
openModal()
|
||||
{
|
||||
openModal() {
|
||||
this.addModall = true;
|
||||
}
|
||||
gotoadd()
|
||||
{
|
||||
this.router.navigate(['../../dashboardbuilder'],{relativeTo:this.route});
|
||||
gotoadd() {
|
||||
this.router.navigate(['../../dashboardbuilder'], { relativeTo: this.route });
|
||||
}
|
||||
goToEdit(id:number)
|
||||
{
|
||||
this.router.navigate(['../dashrunner/'+id],{relativeTo:this.route});
|
||||
// for runner line navigation
|
||||
// goToEditData(id: number){
|
||||
// this.router.navigate(['../editdata/'+id],{relativeTo:this.route});
|
||||
// }
|
||||
goToEdit(id: number) {
|
||||
// Navigate to editnewdash component instead of dashrunnerline
|
||||
// Pass a query parameter to indicate this is from dashboard runner
|
||||
this.router.navigate(['../../dashboardbuilder/editdashn/' + id], {
|
||||
relativeTo: this.route,
|
||||
queryParams: { fromRunner: true }
|
||||
});
|
||||
}
|
||||
|
||||
goToEditData(id: number){
|
||||
this.router.navigate(['../editdata/'+id],{relativeTo:this.route});
|
||||
goToEditData(id: number) {
|
||||
this.router.navigate(['../editdata/' + id], { relativeTo: this.route });
|
||||
}
|
||||
|
||||
onExport() {
|
||||
@@ -84,29 +89,28 @@ export class DashrunnerallComponent implements OnInit {
|
||||
moment().format('YYYYMMDD_HHmmss'))
|
||||
}
|
||||
|
||||
gotoAction(){
|
||||
this.router.navigate(["../../actions"], { relativeTo: this.route, queryParams: { m_id: this.moduleId,pname:this.projectname } });
|
||||
gotoAction() {
|
||||
this.router.navigate(["../../actions"], { relativeTo: this.route, queryParams: { m_id: this.moduleId, pname: this.projectname } });
|
||||
}
|
||||
gotoRepo(){
|
||||
gotoRepo() {
|
||||
this.router.navigate(["../../modulecard"], { relativeTo: this.route, queryParams: { p_id: this.projectId } });
|
||||
}
|
||||
|
||||
onDelete(row){
|
||||
onDelete(row) {
|
||||
this.rowSelected = row;
|
||||
console.log(this.rowSelected);
|
||||
this.modalDelete = true;
|
||||
}
|
||||
delete(id)
|
||||
{
|
||||
this.modalDelete = false;
|
||||
console.log("in delete "+id);
|
||||
this.dashboardService.deleteField(id).subscribe((data)=>{
|
||||
delete(id) {
|
||||
this.modalDelete = false;
|
||||
console.log("in delete " + id);
|
||||
this.dashboardService.deleteField(id).subscribe((data) => {
|
||||
console.log(data);
|
||||
this.ngOnInit();
|
||||
});
|
||||
if (id) {
|
||||
});
|
||||
if (id) {
|
||||
this.toastr.success('Deleted successfully');
|
||||
}
|
||||
}
|
||||
}
|
||||
// openModal()
|
||||
// {
|
||||
|
||||
@@ -254,7 +254,7 @@ export class ReportbuildqueryComponent implements OnInit {
|
||||
name;
|
||||
databaseName;
|
||||
databasename(val) {
|
||||
console.log(val);
|
||||
console.log('connection ', val);
|
||||
this.databaseName = val.name;
|
||||
this.selecteddatabase = val.conn_string;
|
||||
console.log(this.selecteddatabase);
|
||||
|
||||
@@ -23,6 +23,18 @@
|
||||
<label for="workflow_name">{{'ACTIVE'| translate}}</label>
|
||||
<input type="checkbox" formControlName="active" clrToggle value="billable" name="billable" />
|
||||
</div>
|
||||
|
||||
<!-- SureConnect Dropdown -->
|
||||
<div class="clr-col-md-4 clr-col-sm-12">
|
||||
<label for="sureConnectId">SureConnect Connection</label>
|
||||
<select formControlName="sureConnectId" class="clr-select">
|
||||
<option value="">-- Select SureConnect --</option>
|
||||
<option *ngFor="let conn of sureconnectData" [value]="conn.id">
|
||||
{{conn.connection_name || conn.id}}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
<div class="clr-col-md-4 clr-col-sm-12">
|
||||
<label for="url">Get URL</label>
|
||||
|
||||
@@ -4,6 +4,8 @@ import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { ToastrService } from 'ngx-toastr';
|
||||
import { ReportBuilderService } from 'src/app/services/api/report-builder.service';
|
||||
import { SureconnectService } from '../../dashboardnew/sureconnect/sureconnect.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-report-build2add',
|
||||
templateUrl: './report-build2add.component.html',
|
||||
@@ -11,8 +13,12 @@ import { ReportBuilderService } from 'src/app/services/api/report-builder.servic
|
||||
})
|
||||
export class ReportBuild2addComponent implements OnInit {
|
||||
public entryForm: FormGroup;
|
||||
// Add sureconnect data property
|
||||
sureconnectData: any[] = [];
|
||||
|
||||
constructor(private _fb: FormBuilder, private router: Router,private toastr: ToastrService,
|
||||
private route: ActivatedRoute,private reportBuilderService: ReportBuilderService) { }
|
||||
private route: ActivatedRoute,private reportBuilderService: ReportBuilderService,
|
||||
private sureconnectService: SureconnectService) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.entryForm = this._fb.group({
|
||||
@@ -20,9 +26,23 @@ export class ReportBuild2addComponent implements OnInit {
|
||||
description:[null],
|
||||
active:[null],
|
||||
isSql:[false],
|
||||
// Add sureConnectId field to the form
|
||||
sureConnectId: [null],
|
||||
Rpt_builder2_lines: this._fb.array([this.initLinesFormReport()]),
|
||||
});
|
||||
|
||||
// Load sureconnect data
|
||||
this.loadSureconnectData();
|
||||
}
|
||||
|
||||
// Add method to load sureconnect data
|
||||
loadSureconnectData() {
|
||||
this.sureconnectService.getAll().subscribe((data: any[]) => {
|
||||
this.sureconnectData = data;
|
||||
console.log('Sureconnect data loaded:', this.sureconnectData);
|
||||
}, (error) => {
|
||||
console.log('Error loading sureconnect data:', error);
|
||||
});
|
||||
}
|
||||
|
||||
initLinesFormReport() {
|
||||
|
||||
@@ -6,70 +6,87 @@
|
||||
|
||||
<div class="dg-wrapper">
|
||||
<div class="clr-row">
|
||||
<div class="clr-col-4">
|
||||
<h3><b>{{'REPORT_BUILDER_2' | translate}}</b></h3>
|
||||
</div>
|
||||
<div class="clr-col-8" style="text-align: right;">
|
||||
<button id="add" class="btn btn-primary" (click)="gotorunner()">
|
||||
<clr-icon shape="grid-view"></clr-icon>{{'REPORT_RUNNER' | translate}}
|
||||
</button>
|
||||
|
||||
<button id="add" class="btn btn-primary" (click)="goToAdd()">
|
||||
<clr-icon shape="plus"></clr-icon>{{'ADD' | translate}}
|
||||
</button>
|
||||
<div class="clr-col-4">
|
||||
<h3><b>{{'REPORT_BUILDER_2' | translate}}</b></h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clr-col-8" style="text-align: right;">
|
||||
<button id="add" class="btn btn-primary" (click)="gotorunner()">
|
||||
<clr-icon shape="grid-view"></clr-icon>{{'REPORT_RUNNER' | translate}}
|
||||
</button>
|
||||
|
||||
<clr-datagrid [clrDgLoading]="loading">
|
||||
<button id="add" class="btn btn-primary" (click)="goToAdd()">
|
||||
<clr-icon shape="plus"></clr-icon>{{'ADD' | translate}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<clr-datagrid [clrDgLoading]="loading">
|
||||
<clr-dg-placeholder><ng-template #loadingSpinner><clr-spinner>{{'LOADING' | translate}}</clr-spinner></ng-template>
|
||||
<div *ngIf="error;else loadingSpinner">{{error}}</div></clr-dg-placeholder>
|
||||
<div *ngIf="error;else loadingSpinner">{{error}}</div>
|
||||
</clr-dg-placeholder>
|
||||
|
||||
|
||||
<clr-dg-column [clrDgField]="''"><ng-container *clrDgHideableColumn="{hidden: false}">
|
||||
{{'GO_TO' | translate}}
|
||||
</ng-container></clr-dg-column>
|
||||
<clr-dg-column [clrDgField]="'name'"><ng-container *clrDgHideableColumn="{hidden: false}">
|
||||
{{'REPORT_NAME' | translate}}
|
||||
</ng-container></clr-dg-column>
|
||||
<clr-dg-column [clrDgField]="'description'"><ng-container *clrDgHideableColumn="{hidden: false}">
|
||||
{{'REPORT_DESCRIPTION' | translate}}
|
||||
</ng-container></clr-dg-column>
|
||||
<clr-dg-column [clrDgField]="'active'"><ng-container *clrDgHideableColumn="{hidden: false}">
|
||||
{{'ACTIVE' | translate}}
|
||||
</ng-container></clr-dg-column>
|
||||
<clr-dg-column><ng-container *clrDgHideableColumn="{hidden: false}">
|
||||
<clr-icon shape="bars"></clr-icon>{{'ACTION' | translate}}
|
||||
</ng-container></clr-dg-column>
|
||||
{{'GO_TO' | translate}}
|
||||
</ng-container></clr-dg-column>
|
||||
|
||||
<clr-dg-row *clrDgItems="let user of gridData?.slice()?.reverse();" [clrDgItem]="user">
|
||||
<clr-dg-cell><span class="label label-light-blue" style="display: inline;margin-left: 10px; cursor: pointer;" (click)="goToLines(user)"> {{'SET_UP' | translate}}</span></clr-dg-cell>
|
||||
<clr-dg-cell id="word">{{user.reportName}}</clr-dg-cell>
|
||||
<clr-dg-cell id="word">{{user.description}}</clr-dg-cell>
|
||||
<clr-dg-cell id="word">{{user.active}}</clr-dg-cell>
|
||||
<clr-dg-cell>
|
||||
<a href="javascript:void(0)" style="padding-right: 10px;" role="tooltip" aria-haspopup="true" class="tooltip tooltip-sm tooltip-top-left">
|
||||
<span style="cursor: pointer;"><clr-icon shape="trash" (click)="onDelete(user)" class="red is-error" style="color: red;"></clr-icon></span>
|
||||
<span class="tooltip-content"> {{'DELETE' | translate}}</span>
|
||||
</a>
|
||||
<clr-signpost>
|
||||
<span style="cursor: pointer;" clrSignpostTrigger><clr-icon shape="help" class="success" style="color: rgb(0, 130, 236);"></clr-icon></span>
|
||||
<clr-signpost-content [clrPosition]="'left-middle'" *clrIfOpen>
|
||||
<h5 style="margin-top: 0">{{'WHO_COLUMN' | translate}}</h5>
|
||||
<div>{{'ACCOUNT_ID' | translate}}: <code class="clr-code">{{user.accountId}}</code></div>
|
||||
<div>{{'CREATED_AT' | translate}}: <code class="clr-code">{{user.createdAt | date}}</code></div>
|
||||
<div>{{'CREATED_BY' | translate}}: <code class="clr-code">{{user.createdBy}}</code></div>
|
||||
<div>{{'UPDATED_AT' | translate}}: <code class="clr-code">{{user.updatedAt | date}}</code></div>
|
||||
<div>{{'UPDATED_BY' | translate}}: <code class="clr-code">{{user.updatedBy}}</code></div>
|
||||
</clr-signpost-content>
|
||||
</clr-signpost>
|
||||
<clr-dg-column [clrDgField]="'name'"><ng-container *clrDgHideableColumn="{hidden: false}">
|
||||
{{'REPORT_NAME' | translate}}
|
||||
</ng-container></clr-dg-column>
|
||||
<clr-dg-column [clrDgField]="'description'"><ng-container *clrDgHideableColumn="{hidden: false}">
|
||||
{{'REPORT_DESCRIPTION' | translate}}
|
||||
</ng-container></clr-dg-column>
|
||||
|
||||
<!-- <span style="cursor: pointer;"><clr-icon shape="form" (click)="goToLines(user.id)" class="success" style="color: rgb(0, 130, 236);"></clr-icon></span> -->
|
||||
</clr-dg-cell>
|
||||
<clr-dg-action-overflow>
|
||||
<!-- <button class="action-item" (click)="goToEdit(user.id)">Edit <clr-icon shape="edit" class="is-error"></clr-icon></button> -->
|
||||
</clr-dg-action-overflow>
|
||||
<clr-dg-column [clrDgField]="''"><ng-container *clrDgHideableColumn="{hidden: false}">
|
||||
Sureconnect
|
||||
</ng-container></clr-dg-column>
|
||||
|
||||
<!-- <clr-dg-row-detail *clrIfExpanded >
|
||||
<clr-dg-column [clrDgField]="'active'"><ng-container *clrDgHideableColumn="{hidden: false}">
|
||||
{{'ACTIVE' | translate}}
|
||||
</ng-container></clr-dg-column>
|
||||
|
||||
|
||||
|
||||
|
||||
<clr-dg-column><ng-container *clrDgHideableColumn="{hidden: false}">
|
||||
<clr-icon shape="bars"></clr-icon>{{'ACTION' | translate}}
|
||||
</ng-container></clr-dg-column>
|
||||
|
||||
<clr-dg-row *clrDgItems="let user of gridData?.slice()?.reverse();" [clrDgItem]="user">
|
||||
<clr-dg-cell><span class="label label-light-blue" style="display: inline;margin-left: 10px; cursor: pointer;"
|
||||
(click)="goToLines(user)"> {{'SET_UP' | translate}}</span></clr-dg-cell>
|
||||
<clr-dg-cell id="word">{{user.reportName}}</clr-dg-cell>
|
||||
<clr-dg-cell id="word">{{user.description}}</clr-dg-cell>
|
||||
|
||||
<clr-dg-cell id="word">{{user.sureconnect_name}}</clr-dg-cell>
|
||||
<clr-dg-cell id="word">{{user.active}}</clr-dg-cell>
|
||||
<clr-dg-cell>
|
||||
<a href="javascript:void(0)" style="padding-right: 10px;" role="tooltip" aria-haspopup="true"
|
||||
class="tooltip tooltip-sm tooltip-top-left">
|
||||
<span style="cursor: pointer;"><clr-icon shape="trash" (click)="onDelete(user)" class="red is-error"
|
||||
style="color: red;"></clr-icon></span>
|
||||
<span class="tooltip-content"> {{'DELETE' | translate}}</span>
|
||||
</a>
|
||||
<clr-signpost>
|
||||
<span style="cursor: pointer;" clrSignpostTrigger><clr-icon shape="help" class="success"
|
||||
style="color: rgb(0, 130, 236);"></clr-icon></span>
|
||||
<clr-signpost-content [clrPosition]="'left-middle'" *clrIfOpen>
|
||||
<h5 style="margin-top: 0">{{'WHO_COLUMN' | translate}}</h5>
|
||||
<div>{{'ACCOUNT_ID' | translate}}: <code class="clr-code">{{user.accountId}}</code></div>
|
||||
<div>{{'CREATED_AT' | translate}}: <code class="clr-code">{{user.createdAt | date}}</code></div>
|
||||
<div>{{'CREATED_BY' | translate}}: <code class="clr-code">{{user.createdBy}}</code></div>
|
||||
<div>{{'UPDATED_AT' | translate}}: <code class="clr-code">{{user.updatedAt | date}}</code></div>
|
||||
<div>{{'UPDATED_BY' | translate}}: <code class="clr-code">{{user.updatedBy}}</code></div>
|
||||
</clr-signpost-content>
|
||||
</clr-signpost>
|
||||
|
||||
<!-- <span style="cursor: pointer;"><clr-icon shape="form" (click)="goToLines(user.id)" class="success" style="color: rgb(0, 130, 236);"></clr-icon></span> -->
|
||||
</clr-dg-cell>
|
||||
<clr-dg-action-overflow>
|
||||
<!-- <button class="action-item" (click)="goToEdit(user.id)">Edit <clr-icon shape="edit" class="is-error"></clr-icon></button> -->
|
||||
</clr-dg-action-overflow>
|
||||
|
||||
<!-- <clr-dg-row-detail *clrIfExpanded >
|
||||
<table class="table">
|
||||
<tr>
|
||||
<td class="td-title">actionName: </td>
|
||||
@@ -77,26 +94,26 @@
|
||||
</tr>
|
||||
</table>
|
||||
</clr-dg-row-detail> -->
|
||||
</clr-dg-row>
|
||||
</clr-dg-row>
|
||||
|
||||
<clr-dg-footer>
|
||||
<clr-dg-pagination #pagination [clrDgPageSize]="10">
|
||||
<clr-dg-page-size [clrPageSizeOptions]="[10,20,50,100]">{{'USERS_PER_PAGE' | translate}}</clr-dg-page-size>
|
||||
{{pagination.firstItem + 1}} - {{pagination.lastItem + 1}}
|
||||
of {{pagination.totalItems}} users
|
||||
</clr-dg-pagination>
|
||||
</clr-dg-footer>
|
||||
</clr-datagrid>
|
||||
</div>
|
||||
<clr-dg-footer>
|
||||
<clr-dg-pagination #pagination [clrDgPageSize]="10">
|
||||
<clr-dg-page-size [clrPageSizeOptions]="[10,20,50,100]">{{'USERS_PER_PAGE' | translate}}</clr-dg-page-size>
|
||||
{{pagination.firstItem + 1}} - {{pagination.lastItem + 1}}
|
||||
of {{pagination.totalItems}} users
|
||||
</clr-dg-pagination>
|
||||
</clr-dg-footer>
|
||||
</clr-datagrid>
|
||||
</div>
|
||||
|
||||
<clr-modal [(clrModalOpen)]="modaldelete" [clrModalSize]="'lg'" [clrModalStaticBackdrop]="true">
|
||||
<clr-modal [(clrModalOpen)]="modaldelete" [clrModalSize]="'lg'" [clrModalStaticBackdrop]="true">
|
||||
|
||||
<div class="modal-body" *ngIf="rowSelected.id">
|
||||
<h1 class="delete">{{'DELETE_CONFIRMATION' | translate}}</h1>
|
||||
<h2 class="heading">{{rowSelected.id}}</h2>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline" (click)="modaldelete = false">{{'CANCEL' | translate}}</button>
|
||||
<button type="submit" (click)="delete(rowSelected.id)" class="btn btn-primary" >{{'DELETE' | translate}}</button>
|
||||
</div>
|
||||
<div class="modal-body" *ngIf="rowSelected.id">
|
||||
<h1 class="delete">{{'DELETE_CONFIRMATION' | translate}}</h1>
|
||||
<h2 class="heading">{{rowSelected.id}}</h2>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline" (click)="modaldelete = false">{{'CANCEL' | translate}}</button>
|
||||
<button type="submit" (click)="delete(rowSelected.id)" class="btn btn-primary">{{'DELETE' | translate}}</button>
|
||||
</div>
|
||||
</clr-modal>
|
||||
</div>
|
||||
</clr-modal>
|
||||
@@ -1,13 +1,13 @@
|
||||
<div class="container">
|
||||
<h3 style="font-weight: 300;display: inline;"><b>REPORT SET UP - Project Details Report ({{ReportData.id}})</b></h3>
|
||||
<span class="label label-light-blue" style="display: inline;margin-left: 10px;">Edit Mode</span>
|
||||
<hr />
|
||||
<form [formGroup]="entryForm">
|
||||
<div class="clr-row">
|
||||
<div class="clr-col-lg-12 clr-col-md-12 clr-col-sm-12">
|
||||
<div>
|
||||
<div class="clr-row">
|
||||
<!-- <div class="clr-col-md-4 clr-col-sm-12">
|
||||
<h3 style="font-weight: 300;display: inline;"><b>REPORT SET UP - Project Details Report ({{ReportData.id}})</b></h3>
|
||||
<span class="label label-light-blue" style="display: inline;margin-left: 10px;">Edit Mode</span>
|
||||
<hr />
|
||||
<form [formGroup]="entryForm">
|
||||
<div class="clr-row">
|
||||
<div class="clr-col-lg-12 clr-col-md-12 clr-col-sm-12">
|
||||
<div>
|
||||
<div class="clr-row">
|
||||
<!-- <div class="clr-col-md-4 clr-col-sm-12">
|
||||
<div class="clr-col-sm-12">
|
||||
<label for="projectName">Connection Name</label>
|
||||
<select formControlName="conn_name" name="conn_name" [(ngModel)]="nodeEditProperties.conn_name" id="service" class="clr-dropdown">
|
||||
@@ -24,55 +24,70 @@
|
||||
</select>
|
||||
</div>
|
||||
</div> -->
|
||||
<div class="clr-col-md-4 clr-col-sm-12">
|
||||
<label for="url">Get URL</label>
|
||||
<div> <input type="text" class="clr-input" formControlName="url" name="url" [(ngModel)]="nodeEditProperties.url" placeholder="Enter Url" style="width: 76%"> <span><button class="btn btn-icon btn-primary" (click)="getkeys()">
|
||||
<clr-icon shape="view-list"></clr-icon>
|
||||
</button></span></div>
|
||||
</div>
|
||||
<div class="clr-col-md-4 clr-col-sm-12">
|
||||
<label for="workflow_name">Include Date filter</label>
|
||||
<input type="checkbox" formControlName="date_param_req" name="date_param_req" [(ngModel)]="nodeEditProperties.date_param_req" clrToggle />
|
||||
</div>
|
||||
<div class="clr-col-md-4 clr-col-sm-12">
|
||||
<label>Standard Parameters</label>
|
||||
<clr-combobox-container style="margin-top: 0; padding-top: 0;">
|
||||
<!-- <label style="padding-bottom: 5px; padding-top:0px; font-weight: lighter;" class="p1">Select Left Side Filter</label> -->
|
||||
<clr-combobox formControlName="std_param_html" name="std_param_html" [(ngModel)]="nodeEditProperties.std_param_html" clrMulti="true"
|
||||
required>
|
||||
<ng-container *clrOptionSelected="let selected">
|
||||
{{selected}}
|
||||
</ng-container>
|
||||
<clr-options>
|
||||
<clr-option *clrOptionItems="let state of keysfromurl" [clrValue]="state">
|
||||
{{state}}
|
||||
</clr-option>
|
||||
</clr-options>
|
||||
</clr-combobox>
|
||||
</clr-combobox-container>
|
||||
<div class="clr-col-md-4 clr-col-sm-12">
|
||||
<label for="url">Get URL</label>
|
||||
<div> <input type="text" class="clr-input" formControlName="url" name="url"
|
||||
[(ngModel)]="nodeEditProperties.url" placeholder="Enter Url" style="width: 76%"> <span><button
|
||||
class="btn btn-icon btn-primary" (click)="getkeys()">
|
||||
<clr-icon shape="view-list"></clr-icon>
|
||||
</button></span></div>
|
||||
</div>
|
||||
<div class="clr-col-md-4 clr-col-sm-12">
|
||||
<label for="workflow_name">Include Date filter</label>
|
||||
<input type="checkbox" formControlName="date_param_req" name="date_param_req"
|
||||
[(ngModel)]="nodeEditProperties.date_param_req" clrToggle />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="clr-col-md-4 clr-col-sm-12">
|
||||
<label>List</label>
|
||||
<select>
|
||||
<option value="">Choose from list</option>
|
||||
<option></option>
|
||||
</select>
|
||||
<!-- SureConnect Dropdown -->
|
||||
<div class="clr-col-md-4 clr-col-sm-12">
|
||||
<label for="sureConnectId">SureConnect Connection</label>
|
||||
<select formControlName="sureConnectId" class="clr-select">
|
||||
<option value="">-- Select SureConnect --</option>
|
||||
<option *ngFor="let conn of sureconnectData" [value]="conn.id">
|
||||
{{conn.name || conn.id}}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- <div class="clr-col-md-4 clr-col-sm-12">
|
||||
<div class="clr-col-md-4 clr-col-sm-12">
|
||||
<label>Standard Parameters</label>
|
||||
<clr-combobox-container style="margin-top: 0; padding-top: 0;">
|
||||
<!-- <label style="padding-bottom: 5px; padding-top:0px; font-weight: lighter;" class="p1">Select Left Side Filter</label> -->
|
||||
<clr-combobox formControlName="std_param_html" name="std_param_html"
|
||||
[(ngModel)]="nodeEditProperties.std_param_html" clrMulti="true" required>
|
||||
<ng-container *clrOptionSelected="let selected">
|
||||
{{selected}}
|
||||
</ng-container>
|
||||
<clr-options>
|
||||
<clr-option *clrOptionItems="let state of keysfromurl" [clrValue]="state">
|
||||
{{state}}
|
||||
</clr-option>
|
||||
</clr-options>
|
||||
</clr-combobox>
|
||||
</clr-combobox-container>
|
||||
|
||||
</div>
|
||||
<div class="clr-col-md-4 clr-col-sm-12">
|
||||
<label>List</label>
|
||||
<select>
|
||||
<option value="">Choose from list</option>
|
||||
<option></option>
|
||||
</select>
|
||||
|
||||
</div>
|
||||
<!-- <div class="clr-col-md-4 clr-col-sm-12">
|
||||
<div class="clr-col-sm-12">
|
||||
<label for="description" class="d1">Adhoc Parameter String (html)</label>
|
||||
<textarea id="t1" cols="10" rows="3" formControlName="adhoc_param_html" placeholder="Enter Description" name="adhoc_param_html" [(ngModel)]="nodeEditProperties.adhoc_param_html" style="width:100%">
|
||||
</textarea>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<!-- <div class="clr-row" style="padding-left:10px;">
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<!-- <div class="clr-row" style="padding-left:10px;">
|
||||
<div class="clr-col-md-4 clr-col-sm-12">
|
||||
<label for="description" class="d1">Column String (html)</label>
|
||||
<textarea id="t1" cols="10" rows="3" formControlName="column_str" placeholder="Enter Description" name="column_str" [(ngModel)]="nodeEditProperties.column_str" style="width:100%">
|
||||
@@ -85,11 +100,10 @@
|
||||
</textarea>
|
||||
</div>
|
||||
</div> -->
|
||||
<br>
|
||||
<div class="center">
|
||||
<button type="button" class="btn btn-outline" (click)="back()">BACK</button>
|
||||
<button type="submit" form-control class="btn btn-primary" (click)="onSubmit()">UPDATE</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<div class="center">
|
||||
<button type="button" class="btn btn-outline" (click)="back()">BACK</button>
|
||||
<button type="submit" form-control class="btn btn-primary" (click)="onSubmit()">UPDATE</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@@ -3,6 +3,7 @@ import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { ToastrService } from 'ngx-toastr';
|
||||
import { ReportBuilderService } from 'src/app/services/api/report-builder.service';
|
||||
import { SureconnectService } from '../../dashboardnew/sureconnect/sureconnect.service';
|
||||
|
||||
|
||||
@Component({
|
||||
@@ -13,54 +14,75 @@ import { ReportBuilderService } from 'src/app/services/api/report-builder.servic
|
||||
export class ReportBuild2editComponent implements OnInit {
|
||||
public entryForm: FormGroup;
|
||||
updated = false;
|
||||
ReportData:any = {};
|
||||
ReportData: any = {};
|
||||
id: number;
|
||||
nodeEditProperties = {
|
||||
std_param_html:'',
|
||||
adhoc_param_html:'',
|
||||
std_param_html: '',
|
||||
adhoc_param_html: '',
|
||||
// column_str:'',
|
||||
// conn_name:'',
|
||||
date_param_req:'',
|
||||
date_param_req: '',
|
||||
// folderName:'',
|
||||
url:'',
|
||||
url: '',
|
||||
// Add sureConnectId property
|
||||
sureConnectId: null,
|
||||
|
||||
};
|
||||
// Add sureconnect data property
|
||||
sureconnectData: any[] = [];
|
||||
|
||||
};
|
||||
constructor(private router: Router,
|
||||
private route: ActivatedRoute,private reportBuilderService: ReportBuilderService,
|
||||
private toastr: ToastrService, private _fb: FormBuilder) { }
|
||||
private route: ActivatedRoute, private reportBuilderService: ReportBuilderService,
|
||||
private toastr: ToastrService, private _fb: FormBuilder,
|
||||
private sureconnectService: SureconnectService) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.id = this.route.snapshot.params["id"];
|
||||
console.log("update with id = ", this.id);
|
||||
|
||||
this.entryForm = this._fb.group({
|
||||
std_param_html : [null],
|
||||
adhoc_param_html:[null],
|
||||
std_param_html: [null],
|
||||
adhoc_param_html: [null],
|
||||
// column_str:[null],
|
||||
// conn_name:[null],
|
||||
date_param_req:[null],
|
||||
date_param_req: [null],
|
||||
// folderName:[null],
|
||||
url:[null],
|
||||
});
|
||||
url: [null],
|
||||
// Add sureConnectId to form
|
||||
sureConnectId: [null],
|
||||
});
|
||||
|
||||
// Load sureconnect data first, then load report data
|
||||
this.loadSureconnectData();
|
||||
this.getById(this.id);
|
||||
this.listoddatabase();
|
||||
}
|
||||
|
||||
// Add method to load sureconnect data
|
||||
loadSureconnectData() {
|
||||
this.sureconnectService.getAll().subscribe((data: any[]) => {
|
||||
this.sureconnectData = data;
|
||||
console.log('Sureconnect data loaded:', this.sureconnectData);
|
||||
}, (error) => {
|
||||
console.log('Error loading sureconnect data:', error);
|
||||
});
|
||||
}
|
||||
|
||||
databaselist;
|
||||
listoddatabase(){
|
||||
this.reportBuilderService.getdatabse().subscribe((data)=>{
|
||||
this.databaselist=data;
|
||||
listoddatabase() {
|
||||
this.reportBuilderService.getdatabse().subscribe((data) => {
|
||||
this.databaselist = data;
|
||||
console.log(this.databaselist)
|
||||
},(error) => {
|
||||
}, (error) => {
|
||||
console.log(error);
|
||||
if(error){
|
||||
}
|
||||
if (error) {
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
builderLine;
|
||||
lineId;
|
||||
builderLineData:any[] = [];
|
||||
builderLineData: any[] = [];
|
||||
getById(id: number) {
|
||||
this.reportBuilderService.getrbDetailsById(id).subscribe(
|
||||
(data) => {
|
||||
@@ -70,10 +92,9 @@ export class ReportBuild2editComponent implements OnInit {
|
||||
|
||||
this.builderLine = this.ReportData.rpt_builder2_lines;
|
||||
this.lineId = this.builderLine[0].id
|
||||
console.log("line data ",this.lineId, this.builderLine);
|
||||
if(this.builderLine[0].model != '')
|
||||
{
|
||||
this.builderLineData = JSON.parse(this.builderLine[0].model) ;
|
||||
console.log("line data ", this.lineId, this.builderLine);
|
||||
if (this.builderLine[0].model != '') {
|
||||
this.builderLineData = JSON.parse(this.builderLine[0].model);
|
||||
console.log(this.builderLineData);
|
||||
|
||||
this.nodeEditProperties.std_param_html = this.builderLineData[0].std_param_html;
|
||||
@@ -82,6 +103,11 @@ export class ReportBuild2editComponent implements OnInit {
|
||||
// this.nodeEditProperties.conn_name = this.builderLineData.conn_name;
|
||||
this.nodeEditProperties.date_param_req = this.builderLineData[0].date_param_req;
|
||||
this.nodeEditProperties.url = this.builderLineData[0].url;
|
||||
// Set sureConnectId if it exists in the data
|
||||
this.nodeEditProperties.sureConnectId = this.builderLineData[0].sureConnectId || null;
|
||||
|
||||
// Update form with loaded data
|
||||
this.entryForm.patchValue(this.nodeEditProperties);
|
||||
}
|
||||
},
|
||||
(err) => {
|
||||
@@ -92,21 +118,21 @@ export class ReportBuild2editComponent implements OnInit {
|
||||
|
||||
stdparams;
|
||||
keysfromurl;
|
||||
getkeys(){
|
||||
if(this.nodeEditProperties.url !== null){
|
||||
this.reportBuilderService.getcolumnDetailsByurl(this.nodeEditProperties.url).subscribe(data =>{
|
||||
console.log(data);
|
||||
getkeys() {
|
||||
if (this.nodeEditProperties.url !== null) {
|
||||
this.reportBuilderService.getcolumnDetailsByurl(this.nodeEditProperties.url).subscribe(data => {
|
||||
console.log('coloum list data ', data);
|
||||
this.keysfromurl = data;
|
||||
this.nodeEditProperties.adhoc_param_html = this.keysfromurl;
|
||||
this.nodeEditProperties.adhoc_param_html = this.keysfromurl;
|
||||
})
|
||||
}else{
|
||||
} else {
|
||||
this.toastr.error("URL is required");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
listBuilder_Lines = {
|
||||
model:{}
|
||||
model: {}
|
||||
}
|
||||
update() {
|
||||
|
||||
@@ -116,27 +142,32 @@ export class ReportBuild2editComponent implements OnInit {
|
||||
adhoc_param_html: this.nodeEditProperties.adhoc_param_html,
|
||||
date_param_req: this.nodeEditProperties.date_param_req,
|
||||
url: this.nodeEditProperties.url,
|
||||
// Add sureConnectId to the data
|
||||
sureConnectId: this.nodeEditProperties.sureConnectId,
|
||||
};
|
||||
|
||||
this.builderLineData[0].std_param_html = this.nodeEditProperties.std_param_html;
|
||||
this.builderLineData[0].adhoc_param_html = this.nodeEditProperties.adhoc_param_html;
|
||||
this.builderLineData[0].adhoc_param_html = this.nodeEditProperties.adhoc_param_html;
|
||||
// this.builderLineData.column_str = this.nodeEditProperties.column_str;
|
||||
// this.builderLineData.conn_name = this.nodeEditProperties.conn_name ;
|
||||
this.builderLineData[0].date_param_req = this.nodeEditProperties.date_param_req;
|
||||
this.builderLineData[0].url = this.nodeEditProperties.url;
|
||||
// Add sureConnectId to the data
|
||||
this.builderLineData[0].sureConnectId = this.nodeEditProperties.sureConnectId;
|
||||
|
||||
console.log(this.builderLineData);
|
||||
// this.builderLineData.splice(1);
|
||||
console.log(this.builderLineData);
|
||||
let tmp = JSON.stringify(this.builderLineData); //.replace(/\\/g, '')
|
||||
this.listBuilder_Lines.model = tmp;
|
||||
console.log(this.listBuilder_Lines);
|
||||
console.log(this.listBuilder_Lines);
|
||||
|
||||
this.reportBuilderService.updaterbLineData(this.listBuilder_Lines, this.lineId).subscribe(
|
||||
(data) => {
|
||||
console.log(data);
|
||||
if (data) {
|
||||
this.toastr.success('Update successfully');
|
||||
}
|
||||
}
|
||||
this.router.navigate(["../../all"], { relativeTo: this.route });
|
||||
//this.router.navigate(["../../all"],{ relativeTo: this.route, queryParams: { p_id: this.projectId } });
|
||||
},
|
||||
@@ -149,6 +180,8 @@ console.log(this.listBuilder_Lines);
|
||||
|
||||
onSubmit() {
|
||||
this.updated = true;
|
||||
// Update nodeEditProperties with form values including sureConnectId
|
||||
Object.assign(this.nodeEditProperties, this.entryForm.value);
|
||||
this.update();
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -39,6 +39,14 @@
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a href="javascript://" class="nav-link nav-icon modern-nav-icon" routerLinkActive="active"
|
||||
routerLink="/cns-portal/shield-dashboard">
|
||||
<div class="nav-icon-wrapper">
|
||||
<clr-icon shape="shield" solid></clr-icon>
|
||||
<span class="nav-tooltip">Shield Dashboard</span>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a href="javascript://" class="nav-link nav-icon modern-nav-icon" routerLinkActive="active"
|
||||
routerLink="/cns-portal/rerunner/all" (click)="getName()">
|
||||
<div class="nav-icon-wrapper">
|
||||
@@ -122,27 +130,27 @@
|
||||
<a href="javascript://" clrDropdownItem (click)="switchLanguage('en')" class="modern-lang-item">
|
||||
<clr-icon shape="globe" class="lang-icon"></clr-icon>
|
||||
<span>English</span>
|
||||
<div class="lang-flag">ðºð¸</div>
|
||||
<div class="lang-flag">🇺🇸</div>
|
||||
</a>
|
||||
<a href="javascript://" clrDropdownItem (click)="switchLanguage('hi')" class="modern-lang-item">
|
||||
<clr-icon shape="globe" class="lang-icon"></clr-icon>
|
||||
<span>हिनà¥à¤¦à¥</span>
|
||||
<div class="lang-flag">ð®ð³</div>
|
||||
<span>हिन्दी</span>
|
||||
<div class="lang-flag">🇮🇳</div>
|
||||
</a>
|
||||
<a href="javascript://" clrDropdownItem (click)="switchLanguage('ta')" class="modern-lang-item">
|
||||
<clr-icon shape="globe" class="lang-icon"></clr-icon>
|
||||
<span>தமிழà¯</span>
|
||||
<div class="lang-flag">ð®ð³</div>
|
||||
<span>தமிழ்</span>
|
||||
<div class="lang-flag">🇮🇳</div>
|
||||
</a>
|
||||
<a href="javascript://" clrDropdownItem (click)="switchLanguage('pa')" class="modern-lang-item">
|
||||
<clr-icon shape="globe" class="lang-icon"></clr-icon>
|
||||
<span>ਪੰà¨à¨¾à¨¬à©</span>
|
||||
<div class="lang-flag">ð®ð³</div>
|
||||
<span>ਪੰਜਾਬੀ</span>
|
||||
<div class="lang-flag">🇮🇳</div>
|
||||
</a>
|
||||
<a href="javascript://" clrDropdownItem (click)="switchLanguage('ml')" class="modern-lang-item">
|
||||
<clr-icon shape="globe" class="lang-icon"></clr-icon>
|
||||
<span>മലയാളà´</span>
|
||||
<div class="lang-flag">ð®ð³</div>
|
||||
<span>മലയാളം</span>
|
||||
<div class="lang-flag">🇮🇳</div>
|
||||
</a>
|
||||
</clr-dropdown-menu>
|
||||
</clr-dropdown>
|
||||
|
||||
@@ -1,3 +1,26 @@
|
||||
import { Ad10Component } from './BuilderComponents/angulardatatype/Ad10/Ad10.component';
|
||||
|
||||
import { DefatestComponent } from './BuilderComponents/defu/Defatest/Defatest.component';
|
||||
|
||||
|
||||
import { ChildformComponent } from './BuilderComponents/stpkg/Childform/Childform.component';
|
||||
import { DistrictComponent } from './BuilderComponents/testdata/District/District.component';
|
||||
import { StateComponent } from './BuilderComponents/testdata/State/State.component';
|
||||
import { CountryComponent } from './BuilderComponents/testdata/Country/Country.component';
|
||||
import { Ad9Component } from './BuilderComponents/angulardatatype/Ad9/Ad9.component';
|
||||
import { Ad8Component } from './BuilderComponents/angulardatatype/Ad8/Ad8.component';
|
||||
import { Ad7Component } from './BuilderComponents/angulardatatype/Ad7/Ad7.component';
|
||||
import { Ad6Component } from './BuilderComponents/angulardatatype/Ad6/Ad6.component';
|
||||
import { Adv5Component } from './BuilderComponents/angulardatatype/Adv5/Adv5.component';
|
||||
import { Adv4Component } from './BuilderComponents/angulardatatype/Adv4/Adv4.component';
|
||||
import { SupportComponent } from './BuilderComponents/angulardatatype/Support/Support.component';
|
||||
import { Adv3Component } from './BuilderComponents/angulardatatype/Adv3/Adv3.component';
|
||||
import { Dv2Component } from './BuilderComponents/angulardatatype/Dv2/Dv2.component';
|
||||
import { Adv1Component } from './BuilderComponents/angulardatatype/Adv1/Adv1.component';
|
||||
import { Basicp3Component } from './BuilderComponents/angulardatatype/Basicp3/Basicp3.component';
|
||||
import { Basicp2Component } from './BuilderComponents/angulardatatype/Basicp2/Basicp2.component';
|
||||
import { Basicp1Component } from './BuilderComponents/angulardatatype/Basicp1/Basicp1.component';
|
||||
|
||||
|
||||
import { SequencegenaratorComponent } from './fnd/sequencegenarator/sequencegenarator.component';
|
||||
import { Component, NgModule } from '@angular/core';
|
||||
@@ -82,6 +105,17 @@ import { MappingruleallComponent } from './datamanagement/mappingrule/mappingrul
|
||||
import { MappingruleaddComponent } from './datamanagement/mappingrule/mappingruleadd/mappingruleadd.component';
|
||||
import { MappingruleeditComponent } from './datamanagement/mappingrule/mappingruleedit/mappingruleedit.component';
|
||||
import { Stepper_workflowComponent } from './BuilderComponents/stepperworkflow/Stepper_workflow/Stepper_workflow.component';
|
||||
import { AllapiregisteryComponent } from './fnd/apiregistery/allapiregistery/allapiregistery.component';
|
||||
import { AddapiregisteryComponent } from './fnd/apiregistery/addapiregistery/addapiregistery.component';
|
||||
import { EditapiregisteryComponent } from './fnd/apiregistery/editapiregistery/editapiregistery.component';
|
||||
import { ApiregisterylineComponent } from './fnd/apiregistery/Apiregisteryline/Apiregisteryline.component';
|
||||
import { Customer_informationComponent } from './BuilderComponents/angulardatatype/Customer_information/Customer_information.component';
|
||||
import { Deployment_typeComponent } from './BuilderComponents/angulardatatype/Deployment_type/Deployment_type.component';
|
||||
import { ManufacturerComponent } from './BuilderComponents/angulardatatype/Manufacturer/Manufacturer.component';
|
||||
import { Order_summaryComponent } from './BuilderComponents/angulardatatype/Order_summary/Order_summary.component';
|
||||
import { ProductComponent } from './BuilderComponents/angulardatatype/Product/Product.component';
|
||||
import { TypesComponent } from './BuilderComponents/angulardatatype/Types/Types.component';
|
||||
import { Test2Component } from './BuilderComponents/testdata/Test2/Test2.component';
|
||||
import { Token_registeryComponent } from './fnd/Token_registery/Token_registery.component';
|
||||
import { MyworkspaceComponent } from './admin/myworkspace/myworkspace.component';
|
||||
import { ThemeCustomizationComponent } from './theme-customization/theme-customization.component';
|
||||
@@ -89,9 +123,9 @@ import { Data_lakeComponent } from './builder/dashboardnew/Data_lake/Data_lake.c
|
||||
import { SureconnectComponent } from './builder/dashboardnew/sureconnect/sureconnect.component';
|
||||
import { EditsureconnectComponent } from './builder/dashboardnew/sureconnect/editsureconnect/editsureconnect.component';
|
||||
import { OauthComponent } from './builder/dashboardnew/sureconnect/oauth/oauth.component';
|
||||
// import { QueryComponent } from './superadmin/query/query.component';
|
||||
// import { QueryaddComponent } from './superadmin/queryadd/queryadd.component';
|
||||
// import { QueryeditComponent } from './superadmin/queryedit/queryedit.component';
|
||||
import { QueryComponent } from './superadmin/query/query.component';
|
||||
import { QueryaddComponent } from './superadmin/queryadd/queryadd.component';
|
||||
import { QueryeditComponent } from './superadmin/queryedit/queryedit.component';
|
||||
|
||||
|
||||
|
||||
@@ -125,11 +159,13 @@ const routes: Routes = [
|
||||
{ path: 'about', component: AboutComponent },
|
||||
{ path: 'setupicon', component: SetupiconComponent },
|
||||
{ path: 'myworkspace', component: MyworkspaceComponent },
|
||||
{ path: 'theme-customization', component: ThemeCustomizationComponent },
|
||||
{ path: 'datalake', component: Data_lakeComponent },
|
||||
{ path: 'sureconnect', component: SureconnectComponent },
|
||||
{ path: 'oauth', component: OauthComponent },
|
||||
{ path: 'editconnect/:id', component: EditsureconnectComponent },
|
||||
{ path: 'theme-customization', component: ThemeCustomizationComponent },
|
||||
{ path: 'datalake', component: Data_lakeComponent },
|
||||
{ path: 'sureconnect', component: SureconnectComponent },
|
||||
{ path: 'oauth', component: OauthComponent },
|
||||
{ path: 'editconnect/:id', component: EditsureconnectComponent },
|
||||
|
||||
|
||||
|
||||
|
||||
{
|
||||
@@ -143,9 +179,9 @@ const routes: Routes = [
|
||||
|
||||
|
||||
//SUPER ADMIN
|
||||
// { path: 'query', component: QueryComponent, canActivate: [AuthGuard], data: { roles: [Role.Admin] } },
|
||||
// { path: 'reportQuery/:id/queryadd', component: QueryaddComponent, canActivate: [AuthGuard], data: { roles: [Role.Admin] } },
|
||||
// { path: 'reportQuery/queryedit/:id', component: QueryeditComponent, canActivate: [AuthGuard], data: { roles: [Role.Admin] } },
|
||||
{ path: 'query', component: QueryComponent, canActivate: [AuthGuard], data: { roles: [Role.Admin] } },
|
||||
{ path: 'reportQuery/:id/queryadd', component: QueryaddComponent, canActivate: [AuthGuard], data: { roles: [Role.Admin] } },
|
||||
{ path: 'reportQuery/queryedit/:id', component: QueryeditComponent, canActivate: [AuthGuard], data: { roles: [Role.Admin] } },
|
||||
|
||||
|
||||
|
||||
@@ -189,6 +225,12 @@ const routes: Routes = [
|
||||
]
|
||||
},
|
||||
|
||||
// Shield Dashboard
|
||||
{
|
||||
path: 'shield-dashboard',
|
||||
loadChildren: () => import('./builder/dashboardnew/gadgets/shield-dashboard/shield-dashboard-routing.module').then(m => m.ShieldDashboardRoutingModule)
|
||||
},
|
||||
|
||||
{
|
||||
path: 'dashboardrunner', component: DashboardrunnerComponent,
|
||||
children: [
|
||||
@@ -236,8 +278,20 @@ const routes: Routes = [
|
||||
],
|
||||
},
|
||||
{ path: 'SequenceGenerator', component: SequencegenaratorComponent },
|
||||
{ path: 'apiregistery', component: ApiregisteryComponent },
|
||||
|
||||
// Api registery
|
||||
|
||||
{
|
||||
path: 'apiregistery', component: ApiregisteryComponent,
|
||||
children: [
|
||||
{ path: '', redirectTo: 'all', pathMatch: 'full' },
|
||||
{ path: 'all', component: AllapiregisteryComponent },
|
||||
{ path: 'add', component: AddapiregisteryComponent },
|
||||
{ path: 'edit/:id', component: EditapiregisteryComponent },
|
||||
{ path: 'line/:id', component: ApiregisterylineComponent },
|
||||
|
||||
],
|
||||
},
|
||||
|
||||
// DATA MANAGEMENT
|
||||
|
||||
@@ -270,18 +324,186 @@ const routes: Routes = [
|
||||
|
||||
// buildercomponents
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{ path: 'Country', component: CountryComponent },
|
||||
|
||||
|
||||
{ path: 'Adv3', component: Adv3Component },
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{ path: 'Ad10', component: Ad10Component },
|
||||
|
||||
|
||||
{ path: 'Childform', component: ChildformComponent },
|
||||
|
||||
|
||||
{ path: 'District', component: DistrictComponent },
|
||||
|
||||
|
||||
{ path: 'State', component: StateComponent },
|
||||
|
||||
|
||||
{ path: 'Country', component: CountryComponent },
|
||||
|
||||
|
||||
{ path: 'Ad9', component: Ad9Component },
|
||||
|
||||
|
||||
{ path: 'Ad8', component: Ad8Component },
|
||||
|
||||
|
||||
{ path: 'Ad7', component: Ad7Component },
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{ path: 'Ad6', component: Ad6Component },
|
||||
|
||||
|
||||
{ path: 'Adv5', component: Adv5Component },
|
||||
|
||||
|
||||
{ path: 'Support', component: SupportComponent },
|
||||
|
||||
|
||||
{ path: 'Adv3', component: Adv3Component },
|
||||
|
||||
|
||||
{ path: 'tokenregistery', component: Token_registeryComponent },
|
||||
|
||||
|
||||
{ path: 'Defatest', component: DefatestComponent },
|
||||
|
||||
|
||||
{ path: 'Country', component: CountryComponent },
|
||||
|
||||
|
||||
{ path: 'Defatest', component: DefatestComponent },
|
||||
|
||||
{ path: 'Test2', component: Test2Component },
|
||||
|
||||
|
||||
{ path: 'Country', component: CountryComponent },
|
||||
|
||||
|
||||
|
||||
{ path: 'Test2', component: Test2Component },
|
||||
|
||||
{ path: 'Childform', component: ChildformComponent },
|
||||
|
||||
|
||||
{ path: 'District', component: DistrictComponent },
|
||||
|
||||
|
||||
{ path: 'State', component: StateComponent },
|
||||
|
||||
|
||||
{ path: 'Country', component: CountryComponent },
|
||||
|
||||
|
||||
{ path: 'Ad9', component: Ad9Component },
|
||||
|
||||
|
||||
{ path: 'Ad8', component: Ad8Component },
|
||||
|
||||
|
||||
{ path: 'Ad7', component: Ad7Component },
|
||||
|
||||
|
||||
{ path: 'Ad6', component: Ad6Component },
|
||||
|
||||
|
||||
{ path: 'Adv5', component: Adv5Component },
|
||||
|
||||
|
||||
{ path: 'Adv4', component: Adv4Component },
|
||||
|
||||
|
||||
{ path: 'Support', component: SupportComponent },
|
||||
|
||||
|
||||
{ path: 'Adv3', component: Adv3Component },
|
||||
|
||||
|
||||
{ path: 'Dv2', component: Dv2Component },
|
||||
|
||||
|
||||
{ path: 'Adv1', component: Adv1Component },
|
||||
|
||||
|
||||
{ path: 'Basicp3', component: Basicp3Component },
|
||||
|
||||
|
||||
{ path: 'Basicp2', component: Basicp2Component },
|
||||
|
||||
|
||||
{ path: 'Basicp1', component: Basicp1Component },
|
||||
{ path: 'cust', component: Customer_informationComponent },
|
||||
|
||||
{ path: 'Order_summary', component: Order_summaryComponent },
|
||||
|
||||
|
||||
{ path: 'Types', component: TypesComponent },
|
||||
|
||||
|
||||
{ path: 'Product', component: ProductComponent },
|
||||
|
||||
|
||||
{ path: 'Manufacturer', component: ManufacturerComponent },
|
||||
|
||||
|
||||
{ path: 'Deployment_type', component: Deployment_typeComponent },
|
||||
|
||||
|
||||
|
||||
|
||||
{ path: 'Stepper_workflow', component: Stepper_workflowComponent },
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{ path: '**', component: PageNotFoundComponent },
|
||||
|
||||
]
|
||||
|
||||
@@ -1,3 +1,25 @@
|
||||
import { Ad10Component } from './BuilderComponents/angulardatatype/Ad10/Ad10.component';
|
||||
|
||||
import { DefatestComponent } from './BuilderComponents/defu/Defatest/Defatest.component';
|
||||
|
||||
import { ChildformComponent } from './BuilderComponents/stpkg/Childform/Childform.component';
|
||||
import { DistrictComponent } from './BuilderComponents/testdata/District/District.component';
|
||||
import { StateComponent } from './BuilderComponents/testdata/State/State.component';
|
||||
import { CountryComponent } from './BuilderComponents/testdata/Country/Country.component';
|
||||
import { Ad9Component } from './BuilderComponents/angulardatatype/Ad9/Ad9.component';
|
||||
import { Ad8Component } from './BuilderComponents/angulardatatype/Ad8/Ad8.component';
|
||||
import { Ad7Component } from './BuilderComponents/angulardatatype/Ad7/Ad7.component';
|
||||
import { Ad6Component } from './BuilderComponents/angulardatatype/Ad6/Ad6.component';
|
||||
import { Adv5Component } from './BuilderComponents/angulardatatype/Adv5/Adv5.component';
|
||||
import { Adv4Component } from './BuilderComponents/angulardatatype/Adv4/Adv4.component';
|
||||
import { SupportComponent } from './BuilderComponents/angulardatatype/Support/Support.component';
|
||||
import { Adv3Component } from './BuilderComponents/angulardatatype/Adv3/Adv3.component';
|
||||
import { Dv2Component } from './BuilderComponents/angulardatatype/Dv2/Dv2.component';
|
||||
import { Adv1Component } from './BuilderComponents/angulardatatype/Adv1/Adv1.component';
|
||||
import { Basicp3Component } from './BuilderComponents/angulardatatype/Basicp3/Basicp3.component';
|
||||
import { Basicp2Component } from './BuilderComponents/angulardatatype/Basicp2/Basicp2.component';
|
||||
import { Basicp1Component } from './BuilderComponents/angulardatatype/Basicp1/Basicp1.component';
|
||||
|
||||
|
||||
|
||||
import { CommonModule } from '@angular/common';
|
||||
@@ -74,6 +96,9 @@ import { RadarChartComponent } from './builder/dashboardnew/gadgets/radar-chart/
|
||||
import { ScatterChartComponent } from './builder/dashboardnew/gadgets/scatter-chart/scatter-chart.component';
|
||||
import { ToDoChartComponent } from './builder/dashboardnew/gadgets/to-do-chart/to-do-chart.component';
|
||||
import { ScheduleComponent } from './builder/dashboardnew/schedule/schedule.component';
|
||||
import { CommonFilterComponent } from './builder/dashboardnew/common-filter/common-filter.component';
|
||||
import { ChartWrapperComponent } from './builder/dashboardnew/common-filter/chart-wrapper.component';
|
||||
import { CompactFilterComponent } from './builder/dashboardnew/common-filter/compact-filter.component';
|
||||
import { AddextensionComponent } from './fnd/extension/addextension/addextension.component';
|
||||
import { AllextensionComponent } from './fnd/extension/allextension/allextension.component';
|
||||
import { EditextensionComponent } from './fnd/extension/editextension/editextension.component';
|
||||
@@ -91,6 +116,9 @@ import { RadarRunnerComponent } from './builder/dashboardrunner/dashrunnerline/r
|
||||
import { ScatterRunnerComponent } from './builder/dashboardrunner/dashrunnerline/scatter-runner/scatter-runner.component';
|
||||
import { TodoRunnerComponent } from './builder/dashboardrunner/dashrunnerline/todo-runner/todo-runner.component';
|
||||
|
||||
// Import CompactFilterRunnerComponent
|
||||
import { CompactFilterRunnerComponent } from './builder/dashboardrunner/dashrunnerline/compact-filter-runner/compact-filter-runner.component';
|
||||
|
||||
import { ApiregisteryComponent } from './fnd/apiregistery/apiregistery.component';
|
||||
|
||||
import { BulkimportComponent } from './datamanagement/bulkimport/bulkimport.component';
|
||||
@@ -106,18 +134,34 @@ import { MappingruleaddComponent } from './datamanagement/mappingrule/mappingrul
|
||||
import { MappingruleallComponent } from './datamanagement/mappingrule/mappingruleall/mappingruleall.component';
|
||||
import { MappingruleeditComponent } from './datamanagement/mappingrule/mappingruleedit/mappingruleedit.component';
|
||||
import { Stepper_workflowComponent } from './BuilderComponents/stepperworkflow/Stepper_workflow/Stepper_workflow.component';
|
||||
import { AllapiregisteryComponent } from './fnd/apiregistery/allapiregistery/allapiregistery.component';
|
||||
import { AddapiregisteryComponent } from './fnd/apiregistery/addapiregistery/addapiregistery.component';
|
||||
import { EditapiregisteryComponent } from './fnd/apiregistery/editapiregistery/editapiregistery.component';
|
||||
import { ApiregisterylineComponent } from './fnd/apiregistery/Apiregisteryline/Apiregisteryline.component';
|
||||
import { Customer_informationComponent } from './BuilderComponents/angulardatatype/Customer_information/Customer_information.component';
|
||||
import { Deployment_typeComponent } from './BuilderComponents/angulardatatype/Deployment_type/Deployment_type.component';
|
||||
import { ManufacturerComponent } from './BuilderComponents/angulardatatype/Manufacturer/Manufacturer.component';
|
||||
import { Order_summaryComponent } from './BuilderComponents/angulardatatype/Order_summary/Order_summary.component';
|
||||
import { ProductComponent } from './BuilderComponents/angulardatatype/Product/Product.component';
|
||||
import { TypesComponent } from './BuilderComponents/angulardatatype/Types/Types.component';
|
||||
import { Test2Component } from './BuilderComponents/testdata/Test2/Test2.component';
|
||||
import { Token_registeryComponent } from './fnd/Token_registery/Token_registery.component';
|
||||
import { MyworkspaceComponent } from './admin/myworkspace/myworkspace.component';
|
||||
import { ThemeCustomizationComponent } from './theme-customization/theme-customization.component';
|
||||
import { QueryComponent } from './superadmin/query/query.component';
|
||||
import { QueryaddComponent } from './superadmin/queryadd/queryadd.component';
|
||||
import { QueryeditComponent } from './superadmin/queryedit/queryedit.component';
|
||||
|
||||
import { FieldTypesModule } from '../../shared/components/field-types/field-types.module';
|
||||
import { SharedModule } from '../../shared/shared.module';
|
||||
import { Data_lakeComponent } from './builder/dashboardnew/Data_lake/Data_lake.component';
|
||||
import { CronJobBuilderComponent } from './builder/dashboardnew/Data_lake/cron-job-builder/cron-job-builder.component';
|
||||
import { SureconnectComponent } from './builder/dashboardnew/sureconnect/sureconnect.component';
|
||||
import { EditsureconnectComponent } from './builder/dashboardnew/sureconnect/editsureconnect/editsureconnect.component';
|
||||
import { OauthComponent } from './builder/dashboardnew/sureconnect/oauth/oauth.component';
|
||||
|
||||
// import { QueryComponent } from './superadmin/query/query.component';
|
||||
// import { QueryaddComponent } from './superadmin/queryadd/queryadd.component';
|
||||
// import { QueryeditComponent } from './superadmin/queryedit/queryedit.component';
|
||||
// Import Shield Dashboard Module
|
||||
import { ShieldDashboardModule } from './builder/dashboardnew/gadgets/shield-dashboard/shield-dashboard.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
@@ -128,71 +172,58 @@ import { OauthComponent } from './builder/dashboardnew/sureconnect/oauth/oauth.c
|
||||
UsermaintanceaddComponent, UsermaintanceeditComponent,
|
||||
SubmenuComponent, ModulesComponent, SessionloggerComponent,
|
||||
DashboardnewComponent, EditformnewdashComponent, EditnewdashComponent, ScheduleComponent,
|
||||
DoughnutChartComponent, LineChartComponent, RadarChartComponent, BarChartComponent, BubbleChartComponent, DynamicChartComponent, ScatterChartComponent, PolarChartComponent, PieChartComponent, FinancialChartComponent, ToDoChartComponent, GridViewComponent,
|
||||
CommonFilterComponent, ChartWrapperComponent, CompactFilterComponent, DoughnutChartComponent, LineChartComponent, RadarChartComponent, BarChartComponent, BubbleChartComponent, DynamicChartComponent, ScatterChartComponent, PolarChartComponent, PieChartComponent, FinancialChartComponent, ToDoChartComponent, GridViewComponent,
|
||||
DashrunnerlineComponent, BarRunnerComponent, LineRunnerComponent, DoughnutRunnerComponent, GridRunnerComponent, PieRunnerComponent, PolarRunnerComponent, RadarRunnerComponent, ScatterRunnerComponent, TodoRunnerComponent, BubbleRunnerComponent,
|
||||
// Add CompactFilterRunnerComponent to declarations
|
||||
CompactFilterRunnerComponent,
|
||||
ReportBuildComponent, ReportbuildeditComponent, ReportbuildqueryComponent, ReportBuild2Component, ReportBuild2editComponent,
|
||||
// QueryComponent, QueryaddComponent, QueryeditComponent,
|
||||
QueryComponent, QueryaddComponent, QueryeditComponent,
|
||||
ExtensionComponent,
|
||||
AllextensionComponent,
|
||||
AddextensionComponent, EditextensionComponent, ApiregisteryComponent,
|
||||
DatamanagementComponent, DatamananementworkflowComponent, BulkimportComponent, BulkimportallComponent, BulkimportaddComponent, BulkimporteditComponent, BulkimportlineComponent, BulkimporteditlineComponent, MappingruleComponent,
|
||||
MappingruleallComponent, MappingruleaddComponent, MappingruleeditComponent,
|
||||
ThemeCustomizationComponent,
|
||||
AddextensionComponent, EditextensionComponent, ApiregisteryComponent, AllapiregisteryComponent, AddapiregisteryComponent, EditapiregisteryComponent,
|
||||
|
||||
ApiregisterylineComponent,
|
||||
DatamanagementComponent, DatamananementworkflowComponent, BulkimportComponent, BulkimportallComponent, BulkimportaddComponent, BulkimporteditComponent, BulkimportlineComponent, BulkimporteditlineComponent, MappingruleComponent, MappingruleallComponent,
|
||||
MappingruleaddComponent,
|
||||
MappingruleeditComponent, Stepper_workflowComponent, Customer_informationComponent,
|
||||
Data_lakeComponent,
|
||||
SureconnectComponent,
|
||||
EditsureconnectComponent,
|
||||
OauthComponent,
|
||||
CronJobBuilderComponent,
|
||||
SureconnectComponent,
|
||||
EditsureconnectComponent,
|
||||
OauthComponent,
|
||||
CronJobBuilderComponent,
|
||||
// FileUploadListComponent,
|
||||
|
||||
|
||||
// buildercomponents
|
||||
|
||||
|
||||
|
||||
ThemeCustomizationComponent,
|
||||
Ad10Component,
|
||||
Token_registeryComponent,
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Stepper_workflowComponent,
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
DefatestComponent,
|
||||
Test2Component,
|
||||
Order_summaryComponent,
|
||||
TypesComponent,
|
||||
ProductComponent,
|
||||
ManufacturerComponent,
|
||||
Deployment_typeComponent,
|
||||
ChildformComponent,
|
||||
DistrictComponent,
|
||||
StateComponent,
|
||||
CountryComponent,
|
||||
Ad9Component,
|
||||
Ad8Component,
|
||||
Ad7Component,
|
||||
Ad6Component,
|
||||
Adv5Component,
|
||||
Adv4Component,
|
||||
SupportComponent,
|
||||
Adv3Component,
|
||||
Dv2Component,
|
||||
Adv1Component,
|
||||
Basicp3Component,
|
||||
Basicp2Component,
|
||||
Basicp1Component,
|
||||
],
|
||||
imports: [
|
||||
QRCodeModule,
|
||||
@@ -212,6 +243,9 @@ import { OauthComponent } from './builder/dashboardnew/sureconnect/oauth/oauth.c
|
||||
NgChartsModule,
|
||||
NgxChartsModule,
|
||||
DynamicModule,
|
||||
FieldTypesModule,
|
||||
SharedModule,
|
||||
ShieldDashboardModule,
|
||||
],
|
||||
providers: [
|
||||
CookieService,
|
||||
|
||||
@@ -0,0 +1,252 @@
|
||||
import { Ad10Component } from './BuilderComponents/angulardatatype/Ad10/Ad10.component';
|
||||
|
||||
import { DefatestComponent } from './BuilderComponents/defu/Defatest/Defatest.component';
|
||||
|
||||
import { ChildformComponent } from './BuilderComponents/stpkg/Childform/Childform.component';
|
||||
import { DistrictComponent } from './BuilderComponents/testdata/District/District.component';
|
||||
import { StateComponent } from './BuilderComponents/testdata/State/State.component';
|
||||
import { CountryComponent } from './BuilderComponents/testdata/Country/Country.component';
|
||||
import { Ad9Component } from './BuilderComponents/angulardatatype/Ad9/Ad9.component';
|
||||
import { Ad8Component } from './BuilderComponents/angulardatatype/Ad8/Ad8.component';
|
||||
import { Ad7Component } from './BuilderComponents/angulardatatype/Ad7/Ad7.component';
|
||||
import { Ad6Component } from './BuilderComponents/angulardatatype/Ad6/Ad6.component';
|
||||
import { Adv5Component } from './BuilderComponents/angulardatatype/Adv5/Adv5.component';
|
||||
import { Adv4Component } from './BuilderComponents/angulardatatype/Adv4/Adv4.component';
|
||||
import { SupportComponent } from './BuilderComponents/angulardatatype/Support/Support.component';
|
||||
import { Adv3Component } from './BuilderComponents/angulardatatype/Adv3/Adv3.component';
|
||||
import { Dv2Component } from './BuilderComponents/angulardatatype/Dv2/Dv2.component';
|
||||
import { Adv1Component } from './BuilderComponents/angulardatatype/Adv1/Adv1.component';
|
||||
import { Basicp3Component } from './BuilderComponents/angulardatatype/Basicp3/Basicp3.component';
|
||||
import { Basicp2Component } from './BuilderComponents/angulardatatype/Basicp2/Basicp2.component';
|
||||
import { Basicp1Component } from './BuilderComponents/angulardatatype/Basicp1/Basicp1.component';
|
||||
|
||||
|
||||
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { ClarityModule } from '@clr/angular';
|
||||
|
||||
import { MainPageComponent } from '../main/fnd/main-page/main-page.component';
|
||||
import { MainRoutingModule } from './main-routing.module';
|
||||
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
|
||||
// import { AboutComponent } from '../main/admin/about/about.component';
|
||||
// import { LayoutComponent } from './layout/layout.component';
|
||||
import { HelperModule } from 'src/app/pipes/helpers.module';
|
||||
import { PasswordResetComponent } from '../main/admin/password-reset/password-reset.component';
|
||||
import { UserComponent } from '../main/admin/user/user.component';
|
||||
|
||||
|
||||
import { AllMenuGroupComponent } from '../main/admin/menu-group/all/all-menu-group.component';
|
||||
import { EditMenuGroupComponent } from '../main/admin/menu-group/edit/edit-menu-group.component';
|
||||
import { MenuGroupComponent } from '../main/admin/menu-group/menu-group.component';
|
||||
import { ReadOnlyMenuGroupComponent } from '../main/admin/menu-group/read-only/readonly-menu-group.component';
|
||||
import { AddMenurComponent } from '../main/admin/menu-register/add-menur/add-menur.component';
|
||||
import { AllMenurComponent } from '../main/admin/menu-register/all-menur/all-menur.component';
|
||||
import { EditMenurComponent } from '../main/admin/menu-register/edit-menur/edit-menur.component';
|
||||
import { MenuRegisterComponent } from '../main/admin/menu-register/menu-register.component';
|
||||
import { ReadonlyMenurComponent } from '../main/admin/menu-register/readonly-menur/readonly-menur.component';
|
||||
import { ProfileSettingComponent } from '../main/admin/profile-setting/profile-setting.component';
|
||||
import { UsermaintanceaddComponent } from '../main/admin/usermaintanceadd/usermaintanceadd.component';
|
||||
import { UsermaintanceeditComponent } from '../main/admin/usermaintanceedit/usermaintanceedit.component';
|
||||
|
||||
import { DragDropModule } from '@angular/cdk/drag-drop';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { CodemirrorModule } from "@ctrl/ngx-codemirror";
|
||||
import { NgxChartsModule } from '@swimlane/ngx-charts';
|
||||
import { GridsterModule } from 'angular-gridster2';
|
||||
import { DynamicModule } from 'ng-dynamic-component';
|
||||
import { NgChartsModule } from 'ng2-charts';
|
||||
import { CKEditorModule } from 'ng2-ckeditor';
|
||||
|
||||
import { UserRegistrationComponent } from '../main/admin/user-registration/user-registration.component';
|
||||
|
||||
import { QRCodeModule } from 'angularx-qrcode';
|
||||
import { TagInputModule } from 'ngx-chips';
|
||||
import { CookieService } from 'ngx-cookie-service';
|
||||
import { ImageCropperModule } from 'ngx-image-cropper';
|
||||
import { ModulesComponent } from './admin/modules/modules.component';
|
||||
import { SessionloggerComponent } from './admin/sessionlogger/sessionlogger.component';
|
||||
import { SubmenuComponent } from './admin/submenu/submenu.component';
|
||||
|
||||
import { WireframeService } from 'src/app/services/builder/wireframe.service';
|
||||
import { ReportBuildComponent } from './builder/report-build/report-build.component';
|
||||
import { ReportbuildeditComponent } from './builder/report-build/reportbuildedit/reportbuildedit.component';
|
||||
import { ReportbuildqueryComponent } from './builder/report-build/reportbuildquery/reportbuildquery.component';
|
||||
import { ReportBuild2Component } from './builder/report-build2/report-build2.component';
|
||||
import { ReportBuild2editComponent } from './builder/report-build2/report-build2edit/report-build2edit.component';
|
||||
import { ReportRunnerComponent } from './builder/report-runner/report-runner.component';
|
||||
import { ReportrunnereditComponent } from './builder/report-runner/reportrunneredit/reportrunneredit.component';
|
||||
import { Reportrunneredit2Component } from './builder/report-runner/reportrunneredit2/reportrunneredit2.component';
|
||||
|
||||
|
||||
import { DashboardnewComponent } from './builder/dashboardnew/dashboardnew.component';
|
||||
import { EditformnewdashComponent } from './builder/dashboardnew/editformnewdash/editformnewdash.component';
|
||||
import { EditnewdashComponent } from './builder/dashboardnew/editnewdash/editnewdash.component';
|
||||
import { BarChartComponent } from './builder/dashboardnew/gadgets/bar-chart/bar-chart.component';
|
||||
import { BubbleChartComponent } from './builder/dashboardnew/gadgets/bubble-chart/bubble-chart.component';
|
||||
import { DoughnutChartComponent } from './builder/dashboardnew/gadgets/doughnut-chart/doughnut-chart.component';
|
||||
import { DynamicChartComponent } from './builder/dashboardnew/gadgets/dynamic-chart/dynamic-chart.component';
|
||||
import { FinancialChartComponent } from './builder/dashboardnew/gadgets/financial-chart/financial-chart.component';
|
||||
import { GridViewComponent } from './builder/dashboardnew/gadgets/grid-view/grid-view.component';
|
||||
import { LineChartComponent } from './builder/dashboardnew/gadgets/line-chart/line-chart.component';
|
||||
import { PieChartComponent } from './builder/dashboardnew/gadgets/pie-chart/pie-chart.component';
|
||||
import { PolarChartComponent } from './builder/dashboardnew/gadgets/polar-chart/polar-chart.component';
|
||||
import { RadarChartComponent } from './builder/dashboardnew/gadgets/radar-chart/radar-chart.component';
|
||||
import { ScatterChartComponent } from './builder/dashboardnew/gadgets/scatter-chart/scatter-chart.component';
|
||||
import { ToDoChartComponent } from './builder/dashboardnew/gadgets/to-do-chart/to-do-chart.component';
|
||||
import { ScheduleComponent } from './builder/dashboardnew/schedule/schedule.component';
|
||||
import { CommonFilterComponent } from './builder/dashboardnew/common-filter/common-filter.component';
|
||||
import { ChartWrapperComponent } from './builder/dashboardnew/common-filter/chart-wrapper.component';
|
||||
import { AddextensionComponent } from './fnd/extension/addextension/addextension.component';
|
||||
import { AllextensionComponent } from './fnd/extension/allextension/allextension.component';
|
||||
import { EditextensionComponent } from './fnd/extension/editextension/editextension.component';
|
||||
import { ExtensionComponent } from './fnd/extension/extension.component';
|
||||
|
||||
import { BarRunnerComponent } from './builder/dashboardrunner/dashrunnerline/bar-runner/bar-runner.component';
|
||||
import { BubbleRunnerComponent } from './builder/dashboardrunner/dashrunnerline/bubble-runner/bubble-runner.component';
|
||||
import { DashrunnerlineComponent } from './builder/dashboardrunner/dashrunnerline/dashrunnerline.component';
|
||||
import { DoughnutRunnerComponent } from './builder/dashboardrunner/dashrunnerline/doughnut-runner/doughnut-runner.component';
|
||||
import { GridRunnerComponent } from './builder/dashboardrunner/dashrunnerline/grid-runner/grid-runner.component';
|
||||
import { LineRunnerComponent } from './builder/dashboardrunner/dashrunnerline/line-runner/line-runner.component';
|
||||
import { PieRunnerComponent } from './builder/dashboardrunner/dashrunnerline/pie-runner/pie-runner.component';
|
||||
import { PolarRunnerComponent } from './builder/dashboardrunner/dashrunnerline/polar-runner/polar-runner.component';
|
||||
import { RadarRunnerComponent } from './builder/dashboardrunner/dashrunnerline/radar-runner/radar-runner.component';
|
||||
import { ScatterRunnerComponent } from './builder/dashboardrunner/dashrunnerline/scatter-runner/scatter-runner.component';
|
||||
import { TodoRunnerComponent } from './builder/dashboardrunner/dashrunnerline/todo-runner/todo-runner.component';
|
||||
|
||||
import { ApiregisteryComponent } from './fnd/apiregistery/apiregistery.component';
|
||||
|
||||
import { BulkimportComponent } from './datamanagement/bulkimport/bulkimport.component';
|
||||
import { BulkimportaddComponent } from './datamanagement/bulkimport/bulkimportadd/bulkimportadd.component';
|
||||
import { BulkimportallComponent } from './datamanagement/bulkimport/bulkimportall/bulkimportall.component';
|
||||
import { BulkimporteditComponent } from './datamanagement/bulkimport/bulkimportedit/bulkimportedit.component';
|
||||
import { BulkimporteditlineComponent } from './datamanagement/bulkimport/bulkimporteditline/bulkimporteditline.component';
|
||||
import { BulkimportlineComponent } from './datamanagement/bulkimport/bulkimportline/bulkimportline.component';
|
||||
import { DatamanagementComponent } from './datamanagement/datamanagement/datamanagement.component';
|
||||
import { DatamananementworkflowComponent } from './datamanagement/datamananementworkflow/datamananementworkflow.component';
|
||||
import { MappingruleComponent } from './datamanagement/mappingrule/mappingrule.component';
|
||||
import { MappingruleaddComponent } from './datamanagement/mappingrule/mappingruleadd/mappingruleadd.component';
|
||||
import { MappingruleallComponent } from './datamanagement/mappingrule/mappingruleall/mappingruleall.component';
|
||||
import { MappingruleeditComponent } from './datamanagement/mappingrule/mappingruleedit/mappingruleedit.component';
|
||||
import { Stepper_workflowComponent } from './BuilderComponents/stepperworkflow/Stepper_workflow/Stepper_workflow.component';
|
||||
import { AllapiregisteryComponent } from './fnd/apiregistery/allapiregistery/allapiregistery.component';
|
||||
import { AddapiregisteryComponent } from './fnd/apiregistery/addapiregistery/addapiregistery.component';
|
||||
import { EditapiregisteryComponent } from './fnd/apiregistery/editapiregistery/editapiregistery.component';
|
||||
import { ApiregisterylineComponent } from './fnd/apiregistery/Apiregisteryline/Apiregisteryline.component';
|
||||
import { Customer_informationComponent } from './BuilderComponents/angulardatatype/Customer_information/Customer_information.component';
|
||||
import { Deployment_typeComponent } from './BuilderComponents/angulardatatype/Deployment_type/Deployment_type.component';
|
||||
import { ManufacturerComponent } from './BuilderComponents/angulardatatype/Manufacturer/Manufacturer.component';
|
||||
import { Order_summaryComponent } from './BuilderComponents/angulardatatype/Order_summary/Order_summary.component';
|
||||
import { ProductComponent } from './BuilderComponents/angulardatatype/Product/Product.component';
|
||||
import { TypesComponent } from './BuilderComponents/angulardatatype/Types/Types.component';
|
||||
import { Test2Component } from './BuilderComponents/testdata/Test2/Test2.component';
|
||||
import { Token_registeryComponent } from './fnd/Token_registery/Token_registery.component';
|
||||
import { MyworkspaceComponent } from './admin/myworkspace/myworkspace.component';
|
||||
import { ThemeCustomizationComponent } from './theme-customization/theme-customization.component';
|
||||
// import { QueryComponent } from './superadmin/query/query.component';
|
||||
// import { QueryaddComponent } from './superadmin/queryadd/queryadd.component';
|
||||
// import { QueryeditComponent } from './superadmin/queryedit/queryedit.component';
|
||||
|
||||
import { FieldTypesModule } from '../../shared/components/field-types/field-types.module';
|
||||
import { SharedModule } from '../../shared/shared.module';
|
||||
import { Data_lakeComponent } from './builder/dashboardnew/Data_lake/Data_lake.component';
|
||||
import { CronJobBuilderComponent } from './builder/dashboardnew/Data_lake/cron-job-builder/cron-job-builder.component';
|
||||
import { SureconnectComponent } from './builder/dashboardnew/sureconnect/sureconnect.component';
|
||||
import { EditsureconnectComponent } from './builder/dashboardnew/sureconnect/editsureconnect/editsureconnect.component';
|
||||
import { OauthComponent } from './builder/dashboardnew/sureconnect/oauth/oauth.component';
|
||||
|
||||
// Import Shield Dashboard Module
|
||||
import { ShieldDashboardModule } from './builder/dashboardnew/gadgets/shield-dashboard/shield-dashboard.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
MainPageComponent, PageNotFoundComponent, UserComponent, PasswordResetComponent,
|
||||
MyworkspaceComponent,
|
||||
ReportRunnerComponent, ReportrunnereditComponent, Reportrunneredit2Component, MenuGroupComponent, AllMenuGroupComponent, EditMenuGroupComponent, ReadOnlyMenuGroupComponent, UserRegistrationComponent,
|
||||
MenuRegisterComponent, AddMenurComponent, EditMenurComponent, AllMenurComponent, ReadonlyMenurComponent, ProfileSettingComponent,
|
||||
UsermaintanceaddComponent, UsermaintanceeditComponent,
|
||||
SubmenuComponent, ModulesComponent, SessionloggerComponent,
|
||||
DashboardnewComponent, EditformnewdashComponent, EditnewdashComponent, ScheduleComponent,
|
||||
CommonFilterComponent, ChartWrapperComponent, DoughnutChartComponent, LineChartComponent, RadarChartComponent, BarChartComponent, BubbleChartComponent, DynamicChartComponent, ScatterChartComponent, PolarChartComponent, PieChartComponent, FinancialChartComponent, ToDoChartComponent, GridViewComponent,
|
||||
DashrunnerlineComponent, BarRunnerComponent, LineRunnerComponent, DoughnutRunnerComponent, GridRunnerComponent, PieRunnerComponent, PolarRunnerComponent, RadarRunnerComponent, ScatterRunnerComponent, TodoRunnerComponent, BubbleRunnerComponent,
|
||||
ReportBuildComponent, ReportbuildeditComponent, ReportbuildqueryComponent, ReportBuild2Component, ReportBuild2editComponent,
|
||||
// QueryComponent, QueryaddComponent, QueryeditComponent,
|
||||
ExtensionComponent,
|
||||
AllextensionComponent,
|
||||
AddextensionComponent, EditextensionComponent, ApiregisteryComponent, AllapiregisteryComponent, AddapiregisteryComponent, EditapiregisteryComponent,
|
||||
|
||||
ApiregisterylineComponent,
|
||||
DatamanagementComponent, DatamananementworkflowComponent, BulkimportComponent, BulkimportallComponent, BulkimportaddComponent, BulkimporteditComponent, BulkimportlineComponent, BulkimporteditlineComponent, MappingruleComponent, MappingruleallComponent,
|
||||
MappingruleaddComponent,
|
||||
MappingruleeditComponent, Stepper_workflowComponent, Customer_informationComponent,
|
||||
Data_lakeComponent,
|
||||
SureconnectComponent,
|
||||
EditsureconnectComponent,
|
||||
OauthComponent,
|
||||
CronJobBuilderComponent,
|
||||
// FileUploadListComponent,
|
||||
|
||||
|
||||
// buildercomponents
|
||||
|
||||
|
||||
ThemeCustomizationComponent,
|
||||
Ad10Component,
|
||||
Token_registeryComponent,
|
||||
DefatestComponent,
|
||||
Test2Component,
|
||||
Order_summaryComponent,
|
||||
TypesComponent,
|
||||
ProductComponent,
|
||||
ManufacturerComponent,
|
||||
Deployment_typeComponent,
|
||||
ChildformComponent,
|
||||
DistrictComponent,
|
||||
StateComponent,
|
||||
CountryComponent,
|
||||
Ad9Component,
|
||||
Ad8Component,
|
||||
Ad7Component,
|
||||
Ad6Component,
|
||||
Adv5Component,
|
||||
Adv4Component,
|
||||
SupportComponent,
|
||||
Adv3Component,
|
||||
Dv2Component,
|
||||
Adv1Component,
|
||||
Basicp3Component,
|
||||
Basicp2Component,
|
||||
Basicp1Component,
|
||||
],
|
||||
imports: [
|
||||
QRCodeModule,
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
ClarityModule,
|
||||
HelperModule,
|
||||
MainRoutingModule,
|
||||
DragDropModule,
|
||||
HttpClientModule,
|
||||
ImageCropperModule,
|
||||
TagInputModule,
|
||||
CodemirrorModule,
|
||||
CKEditorModule,
|
||||
GridsterModule,
|
||||
NgChartsModule,
|
||||
NgxChartsModule,
|
||||
DynamicModule,
|
||||
FieldTypesModule,
|
||||
SharedModule,
|
||||
ShieldDashboardModule,
|
||||
],
|
||||
providers: [
|
||||
CookieService,
|
||||
WireframeService,
|
||||
|
||||
|
||||
],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||
})
|
||||
export class MainModule { }
|
||||
@@ -69,4 +69,13 @@ export class AlertsService {
|
||||
}
|
||||
return this.apiRequest.get(apiUrl);
|
||||
}
|
||||
|
||||
// Get values for a specific key from API
|
||||
public getValuesFromUrl(url: string, sureId: number | undefined, key: string): Observable<any> {
|
||||
let apiUrl = `chart/getValue?apiUrl=${url}&key=${key}`;
|
||||
if (sureId) {
|
||||
apiUrl += `&sureId=${sureId}`;
|
||||
}
|
||||
return this.apiRequest.get(apiUrl);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user