diff --git a/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/chart-config/dynamic-chart-loader.service.ts b/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/chart-config/dynamic-chart-loader.service.ts new file mode 100644 index 0000000..da26031 --- /dev/null +++ b/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/chart-config/dynamic-chart-loader.service.ts @@ -0,0 +1,117 @@ +import { Injectable } from '@angular/core'; +import { Observable, forkJoin } from 'rxjs'; +import { map } from 'rxjs/operators'; +import { ApiRequestService } from 'src/app/services/api/api-request.service'; +import { ChartType, UiComponent, ComponentProperty, ChartTemplate, DynamicField } from './chart-config-manager.component'; + +@Injectable({ + providedIn: 'root' +}) +export class DynamicChartLoaderService { + private chartTypesUrl = 'api/chart-types'; + private uiComponentsUrl = 'api/ui-components'; + private componentPropertiesUrl = 'api/component-properties'; + private chartTemplatesUrl = 'api/chart-templates'; + private dynamicFieldsUrl = 'api/dynamic-fields'; + + constructor(private apiRequest: ApiRequestService) { } + + /** + * Load all chart configurations dynamically + * This method fetches all chart types and their associated components, templates, and fields + */ + loadAllChartConfigurations(): Observable { + console.log('Loading all chart configurations dynamically'); + + // Load all chart types first + return this.apiRequest.get(this.chartTypesUrl).pipe( + map(chartTypes => { + console.log('Loaded chart types:', chartTypes); + return chartTypes; + }) + ); + } + + /** + * Load complete configuration for a specific chart type + * This includes UI components, templates, and dynamic fields + */ + loadChartConfiguration(chartTypeId: number): Observable<{ + chartType: ChartType, + uiComponents: UiComponent[], + templates: ChartTemplate[], + dynamicFields: DynamicField[] + }> { + console.log(`Loading complete configuration for chart type ${chartTypeId}`); + + // Load all related data in parallel + return forkJoin({ + chartType: this.apiRequest.get(`${this.chartTypesUrl}/${chartTypeId}`), + uiComponents: this.apiRequest.get(`${this.uiComponentsUrl}/chart-type/${chartTypeId}`), + templates: this.apiRequest.get(`${this.chartTemplatesUrl}/chart-type/${chartTypeId}`), + dynamicFields: this.apiRequest.get(`${this.dynamicFieldsUrl}/chart-type/${chartTypeId}`) + }).pipe( + map(result => { + console.log(`Loaded complete configuration for chart type ${chartTypeId}:`, result); + return result; + }) + ); + } + + /** + * Load chart template for a specific chart type + * This is used to render the chart UI dynamically + */ + loadChartTemplate(chartTypeId: number): Observable { + console.log(`Loading chart templates for chart type ${chartTypeId}`); + return this.apiRequest.get(`${this.chartTemplatesUrl}/chart-type/${chartTypeId}`); + } + + /** + * Load UI components for a specific chart type + * These define what configuration fields are needed for the chart + */ + loadUiComponents(chartTypeId: number): Observable { + console.log(`Loading UI components for chart type ${chartTypeId}`); + return this.apiRequest.get(`${this.uiComponentsUrl}/chart-type/${chartTypeId}`); + } + + /** + * Load dynamic fields for a specific chart type + * These define additional dynamic fields that can be used in the chart + */ + loadDynamicFields(chartTypeId: number): Observable { + console.log(`Loading dynamic fields for chart type ${chartTypeId}`); + return this.apiRequest.get(`${this.dynamicFieldsUrl}/chart-type/${chartTypeId}`); + } + + /** + * Get chart type by name + * This is useful for finding a chart type by its name rather than ID + */ + getChartTypeByName(name: string): Observable { + console.log(`Finding chart type by name: ${name}`); + return this.apiRequest.get(`${this.chartTypesUrl}`).pipe( + map((chartTypes: ChartType[]) => { + const chartType = chartTypes.find(ct => ct.name === name); + console.log(`Found chart type for name ${name}:`, chartType); + return chartType || null; + }) + ); + } + + /** + * Load all active chart types + * This is used to populate the chart selection in the dashboard editor + */ + loadActiveChartTypes(): Observable { + console.log('Loading active chart types'); + return this.apiRequest.get(`${this.chartTypesUrl}`).pipe( + map((chartTypes: ChartType[]) => { + const activeChartTypes = chartTypes.filter(ct => ct.isActive); + console.log('Loaded active chart types:', activeChartTypes); + return activeChartTypes; + }) + ); + } +} \ No newline at end of file diff --git a/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/editnewdash/editnewdash.component.html b/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/editnewdash/editnewdash.component.html index 407de1d..0d721e4 100644 --- a/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/editnewdash/editnewdash.component.html +++ b/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/editnewdash/editnewdash.component.html @@ -17,6 +17,9 @@
+
diff --git a/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/editnewdash/editnewdash.component.ts b/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/editnewdash/editnewdash.component.ts index d5e67a2..67eaed6 100644 --- a/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/editnewdash/editnewdash.component.ts +++ b/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/editnewdash/editnewdash.component.ts @@ -30,6 +30,8 @@ import { CompactFilterComponent } from '../common-filter'; import { FilterService } from '../common-filter/filter.service'; // Add the UnifiedChartComponent import import { UnifiedChartComponent } from '../gadgets/unified-chart'; +// Add the DynamicChartLoaderService import +import { DynamicChartLoaderService } from '../chart-config/dynamic-chart-loader.service'; function isNullArray(arr) { return !Array.isArray(arr) || arr.length === 0; @@ -214,7 +216,8 @@ export class EditnewdashComponent implements OnInit { private datastoreService: DatastoreService, private alertService: AlertsService, private sureconnectService: SureconnectService, - private filterService: FilterService) { } // Add SureconnectService and FilterService to constructor + private filterService: FilterService, + private dynamicChartLoader: DynamicChartLoaderService) { } // Add SureconnectService, FilterService, and DynamicChartLoaderService to constructor // Add property to track if coming from dashboard runner fromRunner: boolean = false; @@ -565,20 +568,8 @@ export class EditnewdashComponent implements OnInit { connection: undefined }); case "bar_chart": - return this.dashboardArray.push({ - cols: 5, - rows: 6, - x: 0, - y: 0, - chartid: maxChartId + 1, - component: UnifiedChartComponent, - name: "Bar Chart", - chartType: 'bar', - xAxis: '', - yAxis: '', - table: '', - connection: undefined - }); + // Use dynamic chart creation for bar charts + return this.createDynamicChart('bar', maxChartId); case "pie_chart": return this.dashboardArray.push({ cols: 5, @@ -2045,4 +2036,250 @@ export class EditnewdashComponent implements OnInit { } } + // Add method to apply dynamic template to a chart + applyDynamicTemplate(chartItem: any, template: any) { + console.log('Applying dynamic template to chart:', chartItem, template); + + // Apply HTML template + if (template.templateHtml) { + // In a real implementation, you would dynamically render the HTML template + // For now, we'll just log it + console.log('HTML Template:', template.templateHtml); + } + + // Apply CSS styles + if (template.templateCss) { + // In a real implementation, you would dynamically apply the CSS styles + // For now, we'll just log it + console.log('CSS Template:', template.templateCss); + } + + // Return the chart item with template applied + return { + ...chartItem, + template: template + }; + } + + // Add method to test dynamic chart creation + testDynamicChartCreation() { + console.log('Testing dynamic chart creation'); + + // Show a success message to the user + alert('Dynamic chart test started. Check the browser console for detailed output.'); + + // Load all chart types + this.dynamicChartLoader.loadAllChartConfigurations().subscribe({ + next: (chartTypes) => { + console.log('Loaded chart types:', chartTypes); + + // Find bar chart type + const barChartType = chartTypes.find((ct: any) => ct.name === 'bar'); + if (barChartType) { + console.log('Found bar chart type:', barChartType); + + // Load configuration for bar chart + this.dynamicChartLoader.loadChartConfiguration(barChartType.id).subscribe({ + next: (config) => { + console.log('Loaded bar chart configuration:', config); + + // Create a test chart item + const chartItem = { + cols: 5, + rows: 6, + x: 0, + y: 0, + chartid: 100, + component: UnifiedChartComponent, + name: 'Test Dynamic Bar Chart', + chartType: 'bar', + xAxis: '', + yAxis: '', + table: '', + connection: undefined, + // Add dynamic fields from configuration + dynamicFields: config.dynamicFields || [] + }; + + console.log('Created test chart item:', chartItem); + + // If we have templates, apply the default one + if (config.templates && config.templates.length > 0) { + const defaultTemplate = config.templates.find((t: any) => t.isDefault) || config.templates[0]; + if (defaultTemplate) { + console.log('Applying default template:', defaultTemplate); + const chartWithTemplate = this.applyDynamicTemplate(chartItem, defaultTemplate); + console.log('Chart with template:', chartWithTemplate); + + // Show success message + alert('Dynamic chart test completed successfully! Check console for details.'); + } + } else { + // Show success message even without templates + alert('Dynamic chart test completed successfully! No templates found. Check console for details.'); + } + }, + error: (error) => { + console.error('Error loading bar chart configuration:', error); + alert('Error loading bar chart configuration. Check console for details.'); + } + }); + } else { + console.warn('Bar chart type not found'); + alert('Bar chart type not found in the database.'); + } + }, + error: (error) => { + console.error('Error loading chart types:', error); + alert('Error loading chart types. Check console for details.'); + } + }); + } + + // Add method to load dynamic chart configuration + loadDynamicChartConfiguration(chartTypeId: number) { + console.log(`Loading dynamic chart configuration for chart type ${chartTypeId}`); + this.dynamicChartLoader.loadChartConfiguration(chartTypeId).subscribe({ + next: (config) => { + console.log('Loaded dynamic chart configuration:', config); + // Here you would apply the configuration to the UI + // For example, populate form fields, set up templates, etc. + }, + error: (error) => { + console.error('Error loading dynamic chart configuration:', error); + } + }); + } + + // Add method to load all chart types for dynamic selection + loadChartTypesForSelection() { + console.log('Loading chart types for selection'); + this.dynamicChartLoader.loadActiveChartTypes().subscribe({ + next: (chartTypes) => { + console.log('Loaded chart types for selection:', chartTypes); + // Here you would update the UI to show available chart types + // For example, populate a dropdown or list + }, + error: (error) => { + console.error('Error loading chart types for selection:', error); + } + }); + } + + // Add method to create a dynamic chart with configuration from database + createDynamicChart(chartTypeName: string, maxChartId: number) { + console.log(`Creating dynamic chart of type: ${chartTypeName}`); + + // First, get the chart type by name + this.dynamicChartLoader.getChartTypeByName(chartTypeName).subscribe({ + next: (chartType) => { + if (chartType) { + console.log(`Found chart type:`, chartType); + + // Load the complete configuration for this chart type + this.dynamicChartLoader.loadChartConfiguration(chartType.id).subscribe({ + next: (config) => { + console.log(`Loaded configuration for ${chartTypeName}:`, config); + + // Create the chart item with dynamic configuration + const chartItem = { + cols: 5, + rows: 6, + x: 0, + y: 0, + chartid: maxChartId + 1, + component: UnifiedChartComponent, + name: chartType.displayName || chartTypeName, + chartType: chartType.name, + xAxis: '', + yAxis: '', + table: '', + connection: undefined, + // Add any dynamic fields from the configuration + dynamicFields: config.dynamicFields || [] + }; + + // Add UI components as configuration properties + if (config.uiComponents && config.uiComponents.length > 0) { + config.uiComponents.forEach(component => { + chartItem[component.componentName] = ''; + }); + } + + this.dashboardArray.push(chartItem); + console.log(`Created dynamic chart:`, chartItem); + }, + error: (error) => { + console.error(`Error loading configuration for ${chartTypeName}:`, error); + // Fallback to default configuration + this.createDefaultChart(chartTypeName, maxChartId); + } + }); + } else { + console.warn(`Chart type ${chartTypeName} not found, using default configuration`); + this.createDefaultChart(chartTypeName, maxChartId); + } + }, + error: (error) => { + console.error(`Error finding chart type ${chartTypeName}:`, error); + // Fallback to default configuration + this.createDefaultChart(chartTypeName, maxChartId); + } + }); + } + + // Fallback method to create default chart configuration + createDefaultChart(chartTypeName: string, maxChartId: number) { + console.log(`Creating default chart for ${chartTypeName}`); + + // Map chart type names to chart types + const chartTypeMap = { + 'bar': 'bar', + 'line': 'line', + 'pie': 'pie', + 'doughnut': 'doughnut', + 'radar': 'radar', + 'polar': 'polar', + 'bubble': 'bubble', + 'scatter': 'scatter' + }; + + // Get the chart type from the name + const chartType = chartTypeMap[chartTypeName.toLowerCase()] || 'bar'; + + const chartItem = { + cols: 5, + rows: 6, + x: 0, + y: 0, + chartid: maxChartId + 1, + component: UnifiedChartComponent, + name: this.getChartDisplayName(chartTypeName), + chartType: chartType, + xAxis: '', + yAxis: '', + table: '', + connection: undefined + }; + + this.dashboardArray.push(chartItem); + console.log(`Created default chart:`, chartItem); + } + + // Helper method to get display name for chart type + getChartDisplayName(chartTypeName: string): string { + const displayNameMap = { + 'bar': 'Bar Chart', + 'line': 'Line Chart', + 'pie': 'Pie Chart', + 'doughnut': 'Doughnut Chart', + 'radar': 'Radar Chart', + 'polar': 'Polar Area Chart', + 'bubble': 'Bubble Chart', + 'scatter': 'Scatter Chart' + }; + + return displayNameMap[chartTypeName.toLowerCase()] || chartTypeName; + } + }