"JOB_GET_ALL_LISTITEM": "/api/job/list",
"JOB_GET_BYID": "/api/job/",
"JOB_ADD_ONE": "/api/job/add/",
- "JOB_EDIT_ONE": "/api/job/edit/"
+ "JOB_EDIT_ONE": "/api/job/edit/",
+ "JOB_READ_LOG": "/api/job/log/"
},
"PACKAGE": {
"TEST": "testtest"
--- /dev/null
+'use strict';
+
+var fs = require('fs');
+var JL = require('jsnlog').JL;
+var AppConfig = require('../config.json');
+
+var logger = JL('filesystem.js');
+
+var FileSystem = {};
+
+FileSystem.readLogFile = function readLogFile (req, res) {
+ var strJobId, strJobLogPath;
+
+ logger.info('readLogFile');
+
+ strJobId = req.params.id;
+
+ strJobLogPath = AppConfig.TIC_WEB.PATH + strJobId + '/' + AppConfig.TIC_WEB.LOG_FILE_NAME;
+
+ fs.readFile(strJobLogPath, { encoding: 'utf8' }, function (err, data ) {
+ res.json(data);
+ });
+}
+
+module.exports = FileSystem;
'use strict';
+
/**
* using WebSocket
*/
var client = require('./mariadb');
var session = require('./session');
var config = require('../config.json');
+var filesystem = require('./filesystem');
var JL = require('jsnlog').JL;
var logger = JL('router.js');
client.editJob(req, res);
});
+ /**
+ * Read the log file
+ * @URI /api/job/log/:id
+ * @TYPE POST
+ */
+ router.post('/job/log/:id', function (req, res) {
+ logger.info('an api called that /api/job/log/' + req.params.id);
+ filesystem.readLogFile(req, res);
+ });
+
/*******************
* IMAGES
*******************/
padding-top: 70px;
background: #e1e1e1;
}
+.job-status-ready {
+ font-size: 2vh;
+ display: table-cell;
+}
+.job-status-done {
+ font-size: 2vh;
+ color: blue;
+ display: table-cell;
+}
+.job-status-cancel, .job-status-failed {
+ font-size: 2vh;
+ color: red;
+ display: table-cell;
+}
+.job-status-inprogress {
+ font-size: 2vh;
+ color: green;
+ display: table-cell;
+}
#tic-job-list {
height: calc(100vh - 210px);
display: inline-block;
white-space: nowrap;
vertical-align: middle;
border-radius: 10px;
- background-color: rgba(47, 45, 45, 0.48);
+ background-color: slategray;
}
#tic-job-list .btndownload {
- background-color: #337ab7;
+ background-color: lightseagreen;
}
#tic-job-list .btnnotactive {
pointer-events: none;
opacity: 0.6;
}
#tic-job-list .btncancel {
- background-color: #020202;
+ background-color: darkslategray;
}
.extended_job_table_row {
border: 1px solid #eee;
#tic-job-table td {
height: 38px;
vertical-align: middle;
- padding: 2px;
+ padding: 1px;
}
#tic-job-list-pagination {
display: inline-block;
vertical-align: middle;
}
+
+/* Log View*/
+.log-view-content {
+ z-index: 1982;
+ background-color: #f9f9f9;
+ border: 1px solid #ccc;
+ border-radius: 5px;
+}
+.log-view-content-header {
+ border-bottom-color: #ccc;
+ border-bottom-style: solid;
+ border-bottom-width: thin;
+}
+.log-view-content-close {
+ margin-right: 7px;
+ margin-top: -7px;
+ font-size: 20px;
+}
+.log-view-content-header-title {
+ margin-left: 10px;
+ margin-top: 10px;
+ color: darkslategray;
+}
+.log-view-content-body {
+ margin-left: 10px;
+ margin-right: 10px;
+ margin-bottom: 10px;
+ background-color: rgba(234, 230, 230, 0.78);
+ margin-top: 10px;
+ height: calc(100% - 66px);
+ border-color: gray;
+ border-style: solid;
+ border-width: thin;
+ padding: 4px;
+ overflow-y: scroll;
+ white-space: pre-line;
+}
+a.log-view-content-download {
+ color: cadetblue;
+ float: right;
+ margin-right: 40px;
+ margin-top: -20px;
+ cursor: pointer;
+ font-size: 11px;
+ font-weight: bold;
+}
\ No newline at end of file
</div>
</div><!-- /End Confirm Dialog -->
+ <!-- Log View -->
+ <div id="log-view-content" class="log-view-content">
+ <div class="log-view-content-header">
+ <button type="button" class="close log-view-content-close">x</button>
+ <h4 class="log-view-content-header-title">Log</h4>
+ <a type="button" id="log-view-content-download" class="fa fa-download log-view-content-download"> Download</a>
+ </div>
+ <div id="log-view-content-body" class="log-view-content-body"></div>
+ </div>
+ <!-- /End Log View -->
<!-- library loading -->
<script src="/socket.io/socket.io.js"></script>
$(this).parent().addClass("active");
});
+ // initially, hide the log view
+ // in job and image section
+ $('#log-view-content').hide();
+
}
$(document).ready(function () {
this.jobId = null;
this.jobStatus = null;
this.jobStatusText = null;
+ this.jobStatusClass = null;
this.jobImageName = null;
this.jobImageSize = null;
this.jobPath = null;
this.jobStatusText = value || '';
};
+ JobModel.prototype.getJobStatusClass = function (value) {
+ return this.jobStatusClass;
+ };
+
+ JobModel.prototype.setJobStatusClass = function (value) {
+ this.jobStatusClass = value || '';
+ };
+
JobModel.prototype.getJobStatus = function () {
return this.jobStatus;
};
isDownloadable = false;
statusInfo = JobStatusModel.getStatusInfo(status);
+ /**
+ * statusInfo = {
+ * value: 'READY',
+ * text: 'Ready',
+ * class: 'fa'
+ * }
+ */
this.jobStatus = statusInfo.value || '';
this.setJobStatusText(statusInfo.text);
+ this.setJobStatusClass(statusInfo.class);
if (this.getJobStatus() === DOWNLOADABLE_STATUS) {
isDownloadable = true;
{
value: 'READY',
text: 'Ready',
- class: 'fa fa-toggle-off'
+ class: 'fa fa-circle-o job-status-ready'
},
{
value: 'DONE',
text: 'Done',
- class: 'fa fa-toggle-on'
+ class: 'fa fa-circle job-status-done'
},
{
value: 'CANCELED',
text: 'Canceled',
- class: 'fa fa-toggle-off'
+ class: 'fa fa-ban job-status-cancel'
},
{
value: 'FAILED',
text: 'Failed',
- class: 'fa fa-toggle-off'
+ class: 'fa fa-ban job-status-failed'
},
{
value: 'INPROGRESS',
text: 'In Progress',
- class: 'fa fa-refresh fa-spin'
+ class: 'fa fa-refresh fa-spin job-status-inprogress'
}
];
return this;
ModelJobList = [];
ModelJobPaging;
- function _updateView(arrJobs) {
+ function _hideLogView () {
+ logger.info('_hideLogView');
+
+ }
+ function _readLog (jobId) {
+ logger.info('JOB_READ_LOG: ' + jobId);
+
+ Util.POST(AppConfig.EVENT.JOB.JOB_READ_LOG + jobId)
+ .then(function (line) {
+ $('#log-view-content-body').append(line);
+ });
+ }
+
+ function _showLogView (btn) {
+ var linkid, linkurl, currentPosition, currentWidth, currentHeight;
+
+ logger.info('_showLogView');
+
+ linkid = $(btn).data('jobid');
+ linkurl = $(btn).data('link');
+
+ logger.info('(job_id:' + linkid + ') the url of link is ' + linkurl);
+
+ // get value
+ currentPosition = $('#tic-job-list').offset();
+ currentWidth = $('#tic-job-list').width();
+ currentHeight = $('#tic-job-list').height();
+
+ // set value
+ $('#log-view-content').width(currentWidth);
+ $('#log-view-content').height(currentHeight);
+ $('#log-view-content').offset({
+ top: currentPosition.top,
+ left: currentPosition.left
+ });
+
+ // show
+ $('#log-view-content-body').empty();
+ $('#log-view-content-download').attr('href', linkurl);
+ $('#log-view-content').show();
+ _readLog(linkid);
+ }
+
+ function _updateView (arrJobs) {
return new Promise(function (resolve, reject) {
logger.info('_updateView');
var targetTableBody = $('#tic-job-table > tbody');
_.forEach(arrJobs, function (value, index) {
targetTableBody.append(new JobTableItem(value, index).getRow());
});
+
+ // bind events
+ $('#tic-job-list a.btnbiglog').on('click', function (e) {
+ e.preventDefault();
+ _showLogView(this);
+ });
}
});
}
_initSocket(Util.getWebSocket());
updateList();
});
+
+ $('.log-view-content .log-view-content-close').on('click', function (e) {
+ e.preventDefault();
+ $('#log-view-content-body').empty();
+ $('#log-view-content').hide();
+ });
}
init();
var strRow = [
'<tr id="job_table_row_<%= jobNum %>">',
'<td><%= jobNum %></td>',
- '<td><%= jobStatus %></td>',
- '<td><a class="tic-job-list-btn btndownload" href="<%= jobImagePath %>" title="<%= jobImageName %>">Download</a></td>',
+ '<td class="<%= classJobStatus %>" title="<%= jobStatus %>"></td>',
+ '<td><a class="tic-job-list-btn btndownload <%= classJobImageDownload %>" href="<%= jobImagePath %>" title="<%= jobImageName %> Download">Download</a></td>',
'<td><%= jobImageSize %></td>',
'<td><%= jobUptime %></td>',
'<td><a class="tic-job-list-btn btncancel <%= classJobCancel %>" title="Cancel">Cancel</a></td>',
- '<td><a class="tic-job-list-btn <%= classJobKsPath %>" href="<%= jobKsPath %>" title="KS">KS</a></td>',
- '<td><a class="tic-job-list-btn" href="<%= jobLogPath %>" title="Log">Log</a></td>',
+ '<td><a class="tic-job-list-btn <%= classJobKsPath %>" href="<%= jobKsPath %>" title="Kickstarter File">KS</a></td>',
+ '<td><a class="tic-job-list-btn btnbiglog" data-link="<%= jobLogPath %>" data-jobid="<%= jobNum %>" title="Log">Log</a></td>',
'</tr>'
];
var strExtendedRow = [
'<tr id="job_table_row_<%= jobNum %>">',
'<td><%= jobNum %></td>',
- '<td><%= jobStatus %></td>',
+ '<td class="<%= classJobStatus %>" title="<%= jobStatus %>"></td>',
'<td><a class="tic-job-list-btn btndownload btnnotactive">Download</a></td>',
'<td><%= jobImageSize %></td>',
'<td><%= jobUptime %></td>',
'<td><a class="tic-job-list-btn btncancel <%= classJobCancel %>" title="Cancel">Cancel</a></td>',
- '<td><a class="tic-job-list-btn <%= classJobKsPath %>" href="<%= jobKsPath %>" title="KS">KS</a></td>',
+ '<td><a class="tic-job-list-btn <%= classJobKsPath %>" href="<%= jobKsPath %>" title="Kickstarter File">KS</a></td>',
'<td><a class="tic-job-list-btn" href="<%= jobLogPath %>" title="Log">Log</a></td>',
'</tr>',
'<tr id="extended_job_table_row_<%= jobNum %>" class="extended_job_table_row">',
var temp = _.template(_.join(strRow, ''));
return temp({
'jobNum': data.getJobId(),
+ 'classJobStatus': data.getJobStatusClass(),
'jobStatus': data.getJobStatusText(),
'jobImageName': data.getJobImageName(),
'jobImageSize': data.getJobImageSize(),
'jobImagePath': data.getJobAbsImagePath(),
- 'classJobCancel': statusValue === JOB_STATUS_DONE ? 'btnnotactive' : '',
+ 'classJobImageDownload': data.getJobStatus() === JOB_STATUS_DONE ? '' : 'btnnotactive',
+ 'classJobCancel': statusValue === JOB_STATUS_DONE ? 'btnnotactive' : '',
'classJobKsPath': data.getJobHasKsFile() === '0' ? 'btnnotactive' : '',
'jobKsPath': data.getJobAbsKsPath(),
'jobLogPath': data.getJobAbsLogPath(),
var temp = _.template(_.join(strExtendedRow, ''));
return temp({
'jobNum': data.getJobId(),
+ 'classJobStatus': data.getJobStatusClass(),
'jobStatus': data.getJobStatusText(),
'jobImageName': data.getJobImageName(),
'jobImageSize': data.getJobImageSize(),