diff --git a/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/Data_lake/Data_lake.component.html b/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/Data_lake/Data_lake.component.html index eebfb4a..8921047 100644 --- a/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/Data_lake/Data_lake.component.html +++ b/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/Data_lake/Data_lake.component.html @@ -185,6 +185,13 @@ *ngIf="user.url && user.sure_connect_id"> + + + @@ -1105,4 +1112,69 @@ - \ No newline at end of file + + + + + + \ No newline at end of file diff --git a/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/Data_lake/Data_lake.component.scss b/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/Data_lake/Data_lake.component.scss index b351080..2cbbd07 100644 --- a/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/Data_lake/Data_lake.component.scss +++ b/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/Data_lake/Data_lake.component.scss @@ -683,3 +683,248 @@ padding: 15px; border-top: 1px solid #eee; } + +/* Scheduler Modal Styles */ +.scheduler-container { + padding: 10px; +} + +.data-lake-info h4 { + margin: 0 0 20px 0; + color: #333; + border-bottom: 1px solid #eee; + padding-bottom: 10px; +} + +.job-info-section { + background-color: #f9f9f9; + border: 1px solid #e0e0e0; + border-radius: 6px; + padding: 20px; + margin-bottom: 20px; +} + +.job-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 15px; +} + +.job-header h5 { + margin: 0; + color: #333; +} + +.badge { + padding: 5px 10px; + border-radius: 12px; + font-size: 12px; + font-weight: bold; +} + +.badge-success { + background-color: #4caf50; + color: white; +} + +.badge-warning { + background-color: #ff9800; + color: white; +} + +.badge-danger { + background-color: #f44336; + color: white; +} + +.badge-light { + background-color: #e0e0e0; + color: #333; +} + +.job-details { + margin-bottom: 20px; +} + +.detail-row { + display: flex; + margin-bottom: 10px; +} + +.detail-row label { + font-weight: 500; + width: 120px; + color: #555; +} + +.detail-row span { + flex: 1; +} + +.job-actions { + display: flex; + gap: 10px; + flex-wrap: wrap; +} + +.job-actions .btn { + display: flex; + align-items: center; + gap: 5px; +} + +.no-job-section { + text-align: center; + padding: 30px 20px; +} + +.no-job-message p { + margin: 10px 0; + color: #666; +} + +.no-job-message p:first-child { + font-size: 18px; + color: #333; +} + +.create-job-actions { + margin-top: 20px; +} + +.create-job-actions .btn { + display: inline-flex; + align-items: center; + gap: 5px; +} + +.modal-footer { + display: flex; + justify-content: flex-end; + gap: 10px; + padding: 15px; + border-top: 1px solid #eee; +} +/* Scheduler Modal Styles */ +.scheduler-container { + padding: 10px; +} + +.data-lake-info h4 { + margin: 0 0 20px 0; + color: #333; + border-bottom: 1px solid #eee; + padding-bottom: 10px; +} + +.job-info-section { + background-color: #f9f9f9; + border: 1px solid #e0e0e0; + border-radius: 6px; + padding: 20px; + margin-bottom: 20px; +} + +.job-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 15px; +} + +.job-header h5 { + margin: 0; + color: #333; +} + +.badge { + padding: 5px 10px; + border-radius: 12px; + font-size: 12px; + font-weight: bold; +} + +.badge-success { + background-color: #4caf50; + color: white; +} + +.badge-warning { + background-color: #ff9800; + color: white; +} + +.badge-danger { + background-color: #f44336; + color: white; +} + +.badge-light { + background-color: #e0e0e0; + color: #333; +} + +.job-details { + margin-bottom: 20px; +} + +.detail-row { + display: flex; + margin-bottom: 10px; +} + +.detail-row label { + font-weight: 500; + width: 120px; + color: #555; +} + +.detail-row span { + flex: 1; +} + +.job-actions { + display: flex; + gap: 10px; + flex-wrap: wrap; +} + +.job-actions .btn { + display: flex; + align-items: center; + gap: 5px; +} + +.no-job-section { + text-align: center; + padding: 30px 20px; +} + +.no-job-message p { + margin: 10px 0; + color: #666; +} + +.no-job-message p:first-child { + font-size: 18px; + color: #333; +} + +.create-job-actions { + margin-top: 20px; +} + +.create-job-actions .btn { + display: inline-flex; + align-items: center; + gap: 5px; +} + +.modal-footer { + display: flex; + justify-content: flex-end; + gap: 10px; + padding: 15px; + border-top: 1px solid #eee; +} diff --git a/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/Data_lake/Data_lake.component.ts b/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/Data_lake/Data_lake.component.ts index 33529cd..c2f3e33 100644 --- a/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/Data_lake/Data_lake.component.ts +++ b/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/Data_lake/Data_lake.component.ts @@ -2,6 +2,7 @@ import { Component, OnInit } from '@angular/core'; import { ToastrService } from 'ngx-toastr'; import { AlertService } from 'src/app/services/alert.service'; import { Data_lakeservice } from './Data_lake.service'; +import { SchedulerService } from 'src/app/services/scheduler.service'; import { AbstractControl, FormArray, FormBuilder, FormGroup, Validators, ValidationErrors } from '@angular/forms'; import { ExtensionService } from 'src/app/services/fnd/extension.service'; import { DashboardContentModel2 } from 'src/app/models/builder/dashboard'; @@ -10,6 +11,7 @@ import { UserInfoService } from 'src/app/services/user-info.service'; import { SureconnectService } from '../sureconnect/sureconnect.service'; import { HttpClient } from '@angular/common/http'; import { ApiRequestService } from 'src/app/services/api/api-request.service'; +import { DataLakeSchedulerService } from './dataLakescheduler.service'; declare var JsBarcode: any; @Component({ selector: 'app-Data_lake', @@ -121,10 +123,16 @@ export class Data_lakeComponent implements OnInit { fieldMappings: { [key: string]: string } = {}; selectedMappingItem: any = null; + // New properties for scheduler functionality + showSchedulerModal = false; + schedulerJob: any = null; + selectedSchedulerItem: any = null; + constructor( private extensionService: ExtensionService, private userInfoService: UserInfoService, private mainService: Data_lakeservice, + private schedulerService: DataLakeSchedulerService, private alertService: AlertService, private toastr: ToastrService, private _fb: FormBuilder, @@ -1560,4 +1568,132 @@ export class Data_lakeComponent implements OnInit { this.fieldMappingData[index].mapped = value; } } + + // Method to open scheduler modal + openSchedulerModal(item: any) { + this.selectedSchedulerItem = item; + this.schedulerJob = null; + this.showSchedulerModal = true; + + // Fetch job by lake ID + this.schedulerService.getJobByLakeId(item.id).subscribe( + (job: any) => { + this.schedulerJob = job; + }, + (error) => { + // If job not found, it's expected - we'll show create option + if (error.status === 404) { + this.schedulerJob = null; + } else { + console.error('Error fetching scheduler job:', error); + this.toastr.error('Failed to fetch scheduler job information'); + } + } + ); + } + + // Method to create a new job + createJob() { + if (!this.selectedSchedulerItem) { + this.toastr.error('No data lake selected'); + return; + } + + const jobData = { + name: this.selectedSchedulerItem.name, + status: 'RUNNING', + description: `Scheduled job for ${this.selectedSchedulerItem.name}`, + jobType: 'SYNC', + lakeid: this.selectedSchedulerItem.id + }; + + this.schedulerService.createJob(jobData).subscribe( + (job: any) => { + this.schedulerJob = job; + this.toastr.success('Job created successfully'); + }, + (error) => { + console.error('Error creating job:', error); + this.toastr.error('Failed to create job'); + } + ); + } + + // Method to pause a job + pauseJob() { + if (!this.schedulerJob || !this.schedulerJob.id) { + this.toastr.error('No job selected'); + return; + } + + this.schedulerService.pauseJob(this.schedulerJob.id).subscribe( + (response: any) => { + this.schedulerJob.status = 'PAUSED'; + this.toastr.success('Job paused successfully'); + }, + (error) => { + console.error('Error pausing job:', error); + this.toastr.error('Failed to pause job'); + } + ); + } + + // Method to resume a job + resumeJob() { + if (!this.schedulerJob || !this.schedulerJob.id) { + this.toastr.error('No job selected'); + return; + } + + this.schedulerService.resumeJob(this.schedulerJob.id).subscribe( + (response: any) => { + this.schedulerJob.status = 'RUNNING'; + this.toastr.success('Job resumed successfully'); + }, + (error) => { + console.error('Error resuming job:', error); + this.toastr.error('Failed to resume job'); + } + ); + } + + // Method to stop a job + stopJob() { + if (!this.schedulerJob || !this.schedulerJob.id) { + this.toastr.error('No job selected'); + return; + } + + this.schedulerService.stopJob(this.schedulerJob.id).subscribe( + (response: any) => { + this.schedulerJob.status = 'STOPPED'; + this.toastr.success('Job stopped successfully'); + }, + (error) => { + console.error('Error stopping job:', error); + this.toastr.error('Failed to stop job'); + } + ); + } + + // Method to close scheduler modal + closeSchedulerModal() { + this.showSchedulerModal = false; + this.schedulerJob = null; + this.selectedSchedulerItem = null; + } + + // Method to get status badge class + getStatusBadgeClass(status: string): string { + switch (status) { + case 'RUNNING': + return 'badge-success'; + case 'PAUSED': + return 'badge-warning'; + case 'STOPPED': + return 'badge-danger'; + default: + return 'badge-light'; + } + } } diff --git a/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/Data_lake/dataLakescheduler.service.ts b/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/Data_lake/dataLakescheduler.service.ts new file mode 100644 index 0000000..216a2f7 --- /dev/null +++ b/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/Data_lake/dataLakescheduler.service.ts @@ -0,0 +1,47 @@ + +import { Injectable } from '@angular/core'; +import { Observable } from "rxjs"; +import { HttpClient } from "@angular/common/http"; +import { ApiRequestService } from "src/app/services/api/api-request.service"; + +@Injectable({ + providedIn: 'root' +}) +export class DataLakeSchedulerService { + private baseURL = "scheduler"; + + constructor( + private http: HttpClient, + private apiRequest: ApiRequestService, + ) { } + + // Get job by lake ID + getJobByLakeId(lakeId: number): Observable { + const _http = `${this.baseURL}/lake/${lakeId}`; + return this.apiRequest.get(_http); + } + + // Create a new job + createJob(jobData: any): Observable { + const _http = `${this.baseURL}/create`; + return this.apiRequest.post(_http, jobData); + } + + // Pause a job + pauseJob(jobId: number): Observable { + const _http = `${this.baseURL}/pause/${jobId}`; + return this.apiRequest.post(_http, {}); + } + + // Resume a job + resumeJob(jobId: number): Observable { + const _http = `${this.baseURL}/resume/${jobId}`; + return this.apiRequest.post(_http, {}); + } + + // Stop a job + stopJob(jobId: number): Observable { + const _http = `${this.baseURL}/stop/${jobId}`; + return this.apiRequest.delete(_http); + } +} \ No newline at end of file