diff --git a/swh/web/assets/src/bundles/browse/browse.css b/swh/web/assets/src/bundles/browse/browse.css
--- a/swh/web/assets/src/bundles/browse/browse.css
+++ b/swh/web/assets/src/bundles/browse/browse.css
@@ -40,20 +40,6 @@
display: block;
}
-.swh-metadata-table-row {
- border-top: 1px solid #ddd !important;
-}
-
-.swh-metadata-table-key {
- min-width: 200px;
- max-width: 200px;
- width: 200px;
-}
-
-.swh-metadata-table-value pre {
- white-space: pre-wrap;
-}
-
.swh-table-cell-text-overflow {
white-space: nowrap;
overflow: hidden;
@@ -78,20 +64,6 @@
width: 440px;
}
-.swh-popover {
- max-height: 50vh;
- overflow-y: auto;
- overflow-x: auto;
- padding: 0;
- padding-right: 1.4em;
-}
-
-@media screen and (min-width: 768px) {
- .swh-popover {
- max-width: 80vh;
- }
-}
-
.swh-search-pagination {
margin-top: 5px;
}
diff --git a/swh/web/assets/src/bundles/save/index.js b/swh/web/assets/src/bundles/save/index.js
--- a/swh/web/assets/src/bundles/save/index.js
+++ b/swh/web/assets/src/bundles/save/index.js
@@ -5,9 +5,13 @@
* See top-level LICENSE file for more information
*/
-import {handleFetchError, csrfPost, isGitRepoUrl, htmlAlert, removeUrlFragment} from 'utils/functions';
+import {handleFetchError, csrfPost, isGitRepoUrl, htmlAlert,
+ removeUrlFragment, staticAsset} from 'utils/functions';
import {validate} from 'validate.js';
+// path to static spinner asset
+const swhSpinnerSrc = staticAsset('img/swh-spinner.gif');
+
let saveRequestsTable;
function originSaveRequest(originType, originUrl,
@@ -102,6 +106,17 @@
}
return data;
}
+ },
+ {
+ name: 'info',
+ render: (data, type, row) => {
+ if (row.save_task_status === 'succeed' || row.save_task_status === 'failed') {
+ return '`;
+ } else {
+ return '';
+ }
+ }
}
],
scrollY: '50vh',
@@ -197,10 +212,108 @@
$('.nav-tabs a[href="#swh-origin-save-requests-list"]').tab('show');
}
+ $('body').on('click', e => {
+ if ($(e.target).parents('.popover').length > 0) {
+ event.stopPropagation();
+ } else if ($(e.target).parents('.swh-save-request-info').length === 0) {
+ $('.swh-save-request-info').popover('dispose');
+ }
+ });
+
});
}
+export function displaySaveRequestInfo(event, saveRequestId) {
+ event.stopPropagation();
+ const saveRequestTaskInfoUrl = Urls.origin_save_task_info(saveRequestId);
+ $('.swh-save-request-info').popover('dispose');
+ $(event.target).popover({
+ 'title': 'Save request task information',
+ 'content': `
+
+
![](${swhSpinnerSrc})
+
Fetching task information ...
+
+
`,
+ 'html': true,
+ 'placement': 'left',
+ 'sanitizeFn': swh.webapp.filterXSS
+ });
+ $(event.target).popover('show');
+ fetch(saveRequestTaskInfoUrl)
+ .then(response => response.json())
+ .then(saveRequestTaskInfo => {
+ let content;
+ if ($.isEmptyObject(saveRequestTaskInfo)) {
+ content = 'Not available';
+ } else {
+ let saveRequestInfo = [];
+ saveRequestInfo.push({
+ key: 'Task type',
+ value: saveRequestTaskInfo.type
+ });
+ if (saveRequestTaskInfo.hasOwnProperty('task_name')) {
+ saveRequestInfo.push({
+ key: 'Task name',
+ value: saveRequestTaskInfo.name
+ });
+ }
+ saveRequestInfo.push({
+ key: 'Task arguments',
+ value: JSON.stringify(saveRequestTaskInfo.arguments, null, 2)
+ });
+ saveRequestInfo.push({
+ key: 'Task id',
+ value: saveRequestTaskInfo.id
+ });
+ saveRequestInfo.push({
+ key: 'Task backend id',
+ value: saveRequestTaskInfo.backend_id
+ });
+ saveRequestInfo.push({
+ key: 'Task scheduling date',
+ value: new Date(saveRequestTaskInfo.scheduled).toLocaleString()
+ });
+ saveRequestInfo.push({
+ key: 'Task termination date',
+ value: new Date(saveRequestTaskInfo.ended).toLocaleString()
+ });
+ if (saveRequestTaskInfo.hasOwnProperty('duration')) {
+ saveRequestInfo.push({
+ key: 'Task duration',
+ value: saveRequestTaskInfo.duration + ' s'
+ });
+ }
+ if (saveRequestTaskInfo.hasOwnProperty('worker')) {
+ saveRequestInfo.push({
+ key: 'Task executor',
+ value: saveRequestTaskInfo.worker
+ });
+ }
+ if (saveRequestTaskInfo.hasOwnProperty('message')) {
+ saveRequestInfo.push({
+ key: 'Task log',
+ value: saveRequestTaskInfo.message
+ });
+ }
+ content = '';
+ for (let info of saveRequestInfo) {
+ content +=
+ `
+ ${info.key} |
+
+ ${info.value}
+ |
+
`;
+ }
+ content += '
';
+ }
+ $('.swh-popover').html(content);
+ $(event.target).popover('update');
+ });
+}
+
export function validateSaveOriginUrl(input) {
let originUrl = input.value.trim();
let validUrl = validate({website: originUrl}, {
diff --git a/swh/web/assets/src/bundles/webapp/webapp.css b/swh/web/assets/src/bundles/webapp/webapp.css
--- a/swh/web/assets/src/bundles/webapp/webapp.css
+++ b/swh/web/assets/src/bundles/webapp/webapp.css
@@ -506,3 +506,31 @@
.admonition.warning .first {
font-size: 1.5rem;
}
+
+.swh-popover {
+ max-height: 50vh;
+ overflow-y: auto;
+ overflow-x: auto;
+ padding: 0;
+ padding-right: 1.4em;
+}
+
+@media screen and (min-width: 768px) {
+ .swh-popover {
+ max-width: 50vw;
+ }
+}
+
+.swh-metadata-table-row {
+ border-top: 1px solid #ddd !important;
+}
+
+.swh-metadata-table-key {
+ min-width: 200px;
+ max-width: 200px;
+ width: 200px;
+}
+
+.swh-metadata-table-value pre {
+ white-space: pre-wrap;
+}
diff --git a/swh/web/misc/origin_save.py b/swh/web/misc/origin_save.py
--- a/swh/web/misc/origin_save.py
+++ b/swh/web/misc/origin_save.py
@@ -16,7 +16,8 @@
from swh.web.common.models import SaveOriginRequest
from swh.web.common.origin_save import (
create_save_origin_request, get_savable_origin_types,
- get_save_origin_requests_from_queryset
+ get_save_origin_requests_from_queryset,
+ get_save_origin_task_info
)
from swh.web.common.throttling import throttle_scope
from swh.web.common.utils import EnforceCSRFAuthentication
@@ -91,6 +92,15 @@
return HttpResponse(table_data_json, content_type='application/json')
+def _save_origin_task_info(request, save_request_id):
+ request_info = get_save_origin_task_info(save_request_id)
+ for date_field in ('scheduled', 'started', 'ended'):
+ if date_field in request_info and request_info[date_field] is not None:
+ request_info[date_field] = request_info[date_field].isoformat()
+ return HttpResponse(json.dumps(request_info),
+ content_type='application/json')
+
+
urlpatterns = [
url(r'^save/$', _origin_save_view, name='origin-save'),
url(r'^save/(?P.+)/url/(?P.+)/$',
@@ -99,4 +109,6 @@
name='origin-save-types-list'),
url(r'^save/requests/list/(?P.+)/$', _origin_save_requests_list,
name='origin-save-requests-list'),
+ url(r'^save/task/info/(?P.+)/$', _save_origin_task_info,
+ name='origin-save-task-info'),
]
diff --git a/swh/web/templates/misc/origin-save.html b/swh/web/templates/misc/origin-save.html
--- a/swh/web/templates/misc/origin-save.html
+++ b/swh/web/templates/misc/origin-save.html
@@ -105,6 +105,7 @@
Url |
Request |
Status |
+ Info |