diff --git a/application/controllers/jobs.php b/application/controllers/jobs.php
index 5de1a5f..cf686b6 100644
--- a/application/controllers/jobs.php
+++ b/application/controllers/jobs.php
@@ -29,20 +29,50 @@
class Jobs extends MY_Controller {
/**
- * Constructor.
- */
- public function __construct() {
- parent::__construct();
+ * Constructor.
+ */
+ public function __construct() {
+ parent::__construct();
$this->load->model('job');
$this->load->model('experiment');
$this->load->model('program');
- }
+ }
- /**
- * Starts a job for the specified experiment.
- *
- * @param string $experimentId
- */
+ /**
+ * Shows a list all jobs.
+ */
+ public function index() {
+ $jobs = $this->job->getRecent();
+
+ $data['running_jobs'] = array();
+ foreach ($jobs as $job) {
+ if ($job['status'] == 'running' && $job['started_by'] == $this->session->userdata('user_id')) {
+ $data['running_jobs'][] = $job;
+ }
+ }
+
+ $data['finished_jobs'] = array();
+ foreach ($jobs as $job) {
+ if ($job['status'] == 'complete' && $job['started_by'] == $this->session->userdata('user_id')) {
+ $data['finished_jobs'][] = $job;
+ }
+ }
+
+ $data['pending_jobs'] = array();
+ foreach ($jobs as $job) {
+ if ($job['status'] == 'pending' && $job['started_by'] == $this->session->userdata('user_id')) {
+ $data['pending_jobs'][] = $job;
+ }
+ }
+
+ $this->load->view('jobs/list', $data);
+ }
+
+ /**
+ * Allows users to start a job for the specified experiment.
+ *
+ * @param string $experimentId
+ */
public function start($experimentId = '') {
$experiment = $this->experiment->getByID($experimentId);
if (isset($experiment['id'])) {
@@ -57,6 +87,29 @@ class Jobs extends MY_Controller {
}
}
+ /**
+ * Allows users to cancel the specified job.
+ *
+ * @param string $jobId
+ */
+ public function cancel($jobId) {
+ $this->job->delete($jobId);
+ redirect('jobs');
+ }
+
+ /**
+ * Allows users to mark all finished jobs as seen.
+ */
+ public function mark_all_seen() {
+ $jobs = $this->job->getRecent();
+ foreach ($jobs as $job) {
+ if ($job['status'] == 'complete' && $job['started_by'] == $this->session->userdata('user_id')) {
+ $this->job->markSeen($job['id']);
+ }
+ }
+ redirect('jobs', 303);
+ }
+
/**
* Get jobs belonging to projects owned by the user.
*/
@@ -114,3 +167,6 @@ class Jobs extends MY_Controller {
));
}
}
+
+/* End of file jobs.php */
+/* Location: ./application/controllers/jobs.php */
diff --git a/application/models/job.php b/application/models/job.php
index f39fb97..8048917 100644
--- a/application/models/job.php
+++ b/application/models/job.php
@@ -66,6 +66,22 @@ class Job extends CI_Model {
return $this->db->where('id', $job_id)->update('jobs', $data);
}
+ /**
+ * Marks a finished job as seen.
+ *
+ * @param string $jobId
+ * @return boolean Returns TRUE on success.
+ */
+ public function markSeen($jobId) {
+ $this->db->where('started_by', $this->session->userdata('user_id'));
+ $this->db->where('finished_at !=', 0);
+ $this->db->where('id', $jobId);
+
+ $query = $this->db->update('jobs', array('seen' => 1));
+
+ return $this->db->affected_rows() > 0;
+ }
+
/**
* Gets a specific job.
*
@@ -91,7 +107,7 @@ class Job extends CI_Model {
public function getRecent($projectId = '') {
$this->db->select('jobs.*, experiments.project_id, experiments.name');
$this->db->join('experiments', 'jobs.experiment_id = experiments.id', 'left');
- //$this->db->where('finished_at', 0);
+ $this->db->order_by('created_at DESC');
if (!empty($projectId)) {
$this->db->where('project_id', $projectId);
@@ -99,9 +115,9 @@ class Job extends CI_Model {
$jobs = $this->db->get('jobs')->result_array();
return array_map(function($var) {
- if($var['started_at'] == '0000-00-00 00:00:00') {
+ if ($var['started_at'] == '0000-00-00 00:00:00') {
$var['status'] = 'pending';
- } elseif($var['finished_at'] == '0000-00-00 00:00:00') {
+ } else if ($var['finished_at'] == '0000-00-00 00:00:00') {
$var['status'] = 'running';
} else {
$var['status'] = 'complete';
diff --git a/application/views/jobs/index.html b/application/views/jobs/index.html
new file mode 100755
index 0000000..c942a79
--- /dev/null
+++ b/application/views/jobs/index.html
@@ -0,0 +1,10 @@
+
+
+ 403 Forbidden
+
+
+
+Directory access is forbidden.
+
+
+
\ No newline at end of file
diff --git a/application/views/jobs/list.php b/application/views/jobs/list.php
new file mode 100644
index 0000000..5f69973
--- /dev/null
+++ b/application/views/jobs/list.php
@@ -0,0 +1,131 @@
+load->view('header');?>
+
+
+
+
+
=_('Jobs');?>
+
+
+
+
+
+
+
=_('List of all finished jobs');?>
+
+
+
+ | =_('Name');?> |
+ =_('Finished at');?> |
+ =_('Actions');?> |
+
+
+
+ 0):
+ foreach ($finished_jobs as $job):
+?>
+
+ |
+ =anchor('experiments/detail/' . $job['experiment_id'], $job['name']);?>
+ =($job['seen'] == 0) ? image_asset('icons/new-text.png', 'class="icon"') : '';?>
+ |
+ =relative_time($job['finished_at']);?> |
+
+ =_('Show results');?>
+ |
+
+
+
+ | =_('No finished jobs found.');?> |
+
+
+
+
+
=_('Actions');?>
+
+ =_('Mark all as seen');?>
+ =_('Search job');?>
+
+
+
+
=_('List of all running jobs');?>
+
+
+
+ | =_('Name');?> |
+ =_('Started at');?> |
+ =_('Progress');?> |
+
+
+
+ 0):
+ foreach ($running_jobs as $job):
+?>
+
+ | =anchor('experiments/detail/' . $job['experiment_id'], $job['name']);?> |
+ =relative_time($job['started_at']);?> |
+ =$job['progress'];?>% |
+
+
+
+ | =_('No running jobs found.');?> |
+
+
+
+
+
+
+
=_('List of all pending jobs');?>
+
+
+
+ | =_('Name');?> |
+ =_('Created at');?> |
+ =_('Actions');?> |
+
+
+
+ 0):
+ foreach ($pending_jobs as $job):
+?>
+
+ | =anchor('experiments/detail/' . $job['experiment_id'], $job['name']);?> |
+ =relative_time($job['created_at']);?> |
+
+ =anchor('jobs/cancel/' . $job['id'], _('Cancel'));?>
+ |
+
+
+
+ | =_('No pending jobs found.');?> |
+
+
+
+
+
+
+
+
+
+load->view('footer');?>
diff --git a/assets/css/style.css b/assets/css/style.css
index e13efe8..9aa104d 100644
--- a/assets/css/style.css
+++ b/assets/css/style.css
@@ -41,6 +41,11 @@ li {
margin-left: 20px;
}
+img.icon {
+ vertical-align: middle;
+ margin: 0 2px;
+}
+
.editable {
background: #fffbcc;
}
@@ -569,6 +574,11 @@ a.copy {
padding-left: 30px;
}
+a.clear {
+ background: url(../images/icons/broom.png) 10px center no-repeat #f3f3f3;
+ padding-left: 30px;
+}
+
a.job_start {
background: url(../images/icons/server--arrow.png) 10px center no-repeat #f3f3f3;
padding-left: 30px;