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': `
+
+ +

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 += + ` + + + `; + } + 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