l4i`&bdZddlmZmZmZmZmZmZmZm Z ddl m Z m Z ddl mZGddeZy)Jobs management tab)QWidget QVBoxLayout QHBoxLayout QTableWidgetQTableWidgetItem QPushButton QMessageBox QHeaderView)Qt pyqtSignal)DatabaseManagercxeZdZdZeZfdZdZdZdZ dZ dZ dZ d Z d Zd efd Zd ZdZxZS)JobsTabrct|t|_|j |j y)zInitialize jobs tabN)super__init__rdb_init_uirefresh)self __class__s gui/jobs_tab.pyrzJobsTab.__init__s* !#  c t}|j|t}td|_|jj j |j|j|jtd|_ |jj j |j|j|jtd|_ |jj j |j|j|jtd|_ |jj j |j|j|j|jtd|_|j j j |j"|j|j |j%|t'|_|j(j+d|j(j-gd|j(j/}|j1dt2j4j6|j1d t2j4j8|j1d t2j4j6|j1d t2j4j8|j1d t2j4j6|j1d t2j4j8|j(j;t&j<j>|j(jAt&jBjD|j(jFj |jH|j|j(t}td|_%|jJj j |jL|j|jJtd|_'|jNj j |jP|j|jN|j|j%||jSy)z Create UI layout. Layout: - Top: Button bar (New, Edit, Delete, Clone, Refresh) - Main: Table widget showing jobs - Bottom: Action buttons (Enable/Disable, Execute Now) u ➕ New Jobu ✏️ Editu🗑️ Deleteu 📋 Cloneu 🔄 Refresh)IDNameType ExecutableEnabledScheduleru⏸️ Enable/Disableu▶️ Execute NowN)*r setLayoutrr new_btnclickedconnect create_job addWidgetedit_btnedit_job delete_btn delete_job clone_btn clone_job addStretch refresh_btnr addLayoutrtablesetColumnCountsetHorizontalHeaderLabelshorizontalHeadersetSectionResizeModer ResizeModeResizeToContentsStretchsetSelectionBehaviorSelectionBehavior SelectRowssetSelectionMode SelectionModeSingleSelectionitemSelectionChanged_on_selection_changed toggle_btn toggle_job execute_btn execute_job_update_button_states)rlayout button_layoutheader action_layouts rrzJobsTab._init_uisl v$ "=1  $$T__5 -#M2  %%dmm4 .%&67 ''80$\2 &&t~~6/  "&~6   ((6 0 01'"^  !!!$ ,,.  ,,.##A{'='='N'NO##A{'='='E'EF##A{'='='N'NO##A{'='='E'EF##A{'='='N'NO##A{'='='E'EF '' (F(F(Q(QR ##L$>$>$N$NO ''//0J0JK$$ %&=> ''80&';<   (()9)9: 0 01  "' ""$rc |jjd|jj5}|j }|j d|j }dddD]F}|jj}|jj||jj|dtt|d|jj|dt|d|jj|dt|d|jj|dt|d|drdnd }|jj|dt||d r|d nd }|jj|d t|Iy#1swYWxYw) z Refresh jobs table from database. Steps: 1. Query all jobs from database 2. Get schedule for each job 3. Populate table ra  SELECT j.id, j.name, j.job_type, j.executable_path, j.enabled, s.cron_expression FROM jobs j LEFT JOIN schedules s ON s.job_id = j.id AND s.enabled = 1 ORDER BY j.name Nr#r$r%r&u✓ Yesu✗ Nor'z (no schedule)) r7 setRowCountrget_connectioncursorexecutefetchallrowCount insertRowsetItemrstr)rconnrSjobsjobrow enabled_text schedule_texts rrzJobsTab.refreshis q! WW # # % %[[]F NN ??$D % HC**%%'C JJ  % JJ  sA'7CF 'D E JJ  sA'7A'? @ JJ  sA'7A'? @ JJ  sA'7A'? @),A9HL JJ  sA'7 'E F'*!fCF/M JJ  sA'7 'F G- H % %s 2F==Gcddlm}||}|jr+|j|jj yy)zW Open dialog to create new job. Uses JobDialog in create mode r# JobDialogN) job_dialogrbexecr jobs_modifiedemit)rrbdialogs rr,zJobsTab.create_jobs9 *4 ;;= LLN    # # % rc|j}|syddlm}|||}|jr+|j |j j yy)zEdit selected jobNr#ra)job_id)_get_selected_job_idrcrbrdrrerf)rrirbrgs rr/zJobsTab.edit_jobsN**, )4/ ;;= LLN    # # % rc|j}|sy|jj|jjdj }t j |dd|dt jjt jjz}|t jjk(rq|jj5}|j}|jd|fddd|j|jj!yy#1swY5xYw)z%Delete selected job with confirmationNr#zConfirm Deletez%Are you sure you want to delete job 'z='? This will also delete its schedule and execution history.zDELETE FROM jobs WHERE id = ?)rjr7item currentRowtextr questionStandardButtonYesNorrRrSrTrrerf)rrijob_namereplyrZrSs rr1zJobsTab.delete_jobs **, ::??4::#8#8#:A>CCE$$  3H:>H H  & & * *[-G-G-J-J J   K..22 2'') KT> J K LLN    # # % 3 K Ks $D44D=c n|j}|sy|jj5}|j}|j d|f|j }dddddlm}|jj}|jj5}|j}|j ddd|d|d |d |d dd |d||f ddd|j|jjy#1swYxYw#1swY@xYw) z Clone selected job with new nameNSELECT * FROM jobs WHERE id = ?r)datetimez INSERT INTO jobs (name, job_type, executable_path, working_directory, timeout, enabled, description, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) name_copyjob_typeexecutable_pathworking_directorytimeoutzCopy of ) rjrrRrSrTfetchonerwnow isoformatrrerf)rrirZrSr\rwrs rr3zJobsTab.clone_jobs,**, WW # # % $[[]F NNrs-( j3gj3r