Changeset View
Standalone View
assets/src/bundles/save/index.js
/** | /** | ||||
* Copyright (C) 2018-2020 The Software Heritage developers | * Copyright (C) 2018-2021 The Software Heritage developers | ||||
* See the AUTHORS file at the top-level directory of this distribution | * See the AUTHORS file at the top-level directory of this distribution | ||||
* License: GNU Affero General Public License version 3, or any later version | * License: GNU Affero General Public License version 3, or any later version | ||||
* See top-level LICENSE file for more information | * See top-level LICENSE file for more information | ||||
*/ | */ | ||||
import {handleFetchError, csrfPost, isGitRepoUrl, htmlAlert, removeUrlFragment} from 'utils/functions'; | import {handleFetchError, csrfPost, isGitRepoUrl, htmlAlert, removeUrlFragment} from 'utils/functions'; | ||||
import {swhSpinnerSrc} from 'utils/constants'; | import {swhSpinnerSrc} from 'utils/constants'; | ||||
▲ Show 20 Lines • Show All 320 Lines • ▼ Show 20 Lines | $('#swh-take-new-snapshot-form').submit(event => { | ||||
} else { | } else { | ||||
$('#swh-take-new-snapshot-request-status').html(newSnapshotRequestUnknownErrorAlert); | $('#swh-take-new-snapshot-request-status').html(newSnapshotRequestUnknownErrorAlert); | ||||
} | } | ||||
}); | }); | ||||
}); | }); | ||||
}); | }); | ||||
} | } | ||||
export function formatValuePerType(type, value) { | |||||
// Given some typed value, format and return accordingly formatted value | |||||
const mapFormatPerTypeFn = { | |||||
'json': (v) => JSON.stringify(v, null, 2), | |||||
'date': (v) => new Date(v).toLocaleString(), | |||||
'raw': (v) => v, | |||||
'duration': (v) => v + ' seconds' | |||||
}; | |||||
return mapFormatPerTypeFn[type](value); | |||||
} | |||||
export function displaySaveRequestInfo(event, saveRequestId) { | export function displaySaveRequestInfo(event, saveRequestId) { | ||||
event.stopPropagation(); | event.stopPropagation(); | ||||
const saveRequestTaskInfoUrl = Urls.origin_save_task_info(saveRequestId); | const saveRequestTaskInfoUrl = Urls.origin_save_task_info(saveRequestId); | ||||
// close popover when clicking again on the info icon | // close popover when clicking again on the info icon | ||||
if ($(event.target).data('bs.popover')) { | if ($(event.target).data('bs.popover')) { | ||||
$(event.target).popover('dispose'); | $(event.target).popover('dispose'); | ||||
return; | return; | ||||
} | } | ||||
Show All 26 Lines | export function displaySaveRequestInfo(event, saveRequestId) { | ||||
$(event.target).popover('show'); | $(event.target).popover('show'); | ||||
fetch(saveRequestTaskInfoUrl) | fetch(saveRequestTaskInfoUrl) | ||||
.then(response => response.json()) | .then(response => response.json()) | ||||
.then(saveRequestTaskInfo => { | .then(saveRequestTaskInfo => { | ||||
let content; | let content; | ||||
if ($.isEmptyObject(saveRequestTaskInfo)) { | if ($.isEmptyObject(saveRequestTaskInfo)) { | ||||
content = 'Not available'; | content = 'Not available'; | ||||
} else { | } else { | ||||
let saveRequestInfo = []; | let saveRequestInfo = []; | ||||
if (saveRequestTaskInfo.type) { | const taskData = { | ||||
saveRequestInfo.push({ | 'Type': ['raw', 'type'], | ||||
key: 'Task type', | 'Visit status': ['raw', 'visit_status'], | ||||
value: saveRequestTaskInfo.type | 'Arguments': ['json', 'arguments'], | ||||
}); | 'Id': ['raw', 'id'], | ||||
} | 'Backend id': ['raw', 'backend_id'], | ||||
if (saveRequestTaskInfo.arguments) { | 'Scheduling date': ['date', 'scheduled'], | ||||
saveRequestInfo.push({ | 'Start date': ['date', 'started'], | ||||
key: 'Task arguments', | 'Termination date': ['date', 'ended'], | ||||
value: JSON.stringify(saveRequestTaskInfo.arguments, null, 2) | 'Duration': ['duration', 'duration'], | ||||
}); | 'Executor': ['raw', 'worker'], | ||||
} | 'Log': ['raw', 'message'] | ||||
if (saveRequestTaskInfo.id) { | }; | ||||
saveRequestInfo.push({ | for (const [title, [type, property]] of Object.entries(taskData)) { | ||||
key: 'Task id', | if (saveRequestTaskInfo.hasOwnProperty(property)) { | ||||
value: saveRequestTaskInfo.id | |||||
}); | |||||
} | |||||
if (saveRequestTaskInfo.backend_id) { | |||||
saveRequestInfo.push({ | |||||
key: 'Task backend id', | |||||
value: saveRequestTaskInfo.backend_id | |||||
}); | |||||
} | |||||
if (saveRequestTaskInfo.scheduled) { | |||||
saveRequestInfo.push({ | |||||
key: 'Task scheduling date', | |||||
value: new Date(saveRequestTaskInfo.scheduled).toLocaleString() | |||||
}); | |||||
} | |||||
if (saveRequestTaskInfo.started) { | |||||
saveRequestInfo.push({ | |||||
key: 'Task start date', | |||||
value: new Date(saveRequestTaskInfo.started).toLocaleString() | |||||
}); | |||||
} | |||||
if (saveRequestTaskInfo.ended) { | |||||
saveRequestInfo.push({ | |||||
key: 'Task termination date', | |||||
value: new Date(saveRequestTaskInfo.ended).toLocaleString() | |||||
}); | |||||
} | |||||
if (saveRequestTaskInfo.duration) { | |||||
saveRequestInfo.push({ | |||||
key: 'Task duration', | |||||
value: saveRequestTaskInfo.duration + ' seconds' | |||||
}); | |||||
} | |||||
if (saveRequestTaskInfo.worker) { | |||||
saveRequestInfo.push({ | saveRequestInfo.push({ | ||||
key: 'Task executor', | key: title, | ||||
value: saveRequestTaskInfo.worker | value: formatValuePerType(type, saveRequestTaskInfo[property]) | ||||
}); | }); | ||||
} | } | ||||
anlambert: Looking at this code I wrote at the time, I should have written it like that instead… | |||||
Done Inline Actionsthat will be a tad more complicated than that, we'll need types as well. There is json (arguments), dates (scheduled, started, ended), duration (duration i think), and raw values, etc... I'll try something... ardumont: that will be a tad more complicated than that, we'll need types as well.
There is json… | |||||
Not Done Inline ActionsYou could do something like that then: const taskData = { "Type": {"property": "type", "transform": x => x}, "Start date": {"property": "started", "transform": x => new Date(x).toLocaleString()}, ... }; for (const [title, data] of Object.entries(taskData)) { if (saveRequestTaskInfo.hasOwnProperty(data.property)) { saveRequestInfo.push({ key: title, value: data.transform(saveRequestTaskInfo[data.property]) }); } } anlambert: You could do something like that then:
```lang=javascript
const taskData = {
"Type"… | |||||
Done Inline Actionsoh no... ;) No idea if that would work, just thrown out there... just to show it'd be more complicated than entertained. There is potential issues... with the following. First with the destructuring, which i've no idea if that would work. export function formatValuePerType(type, value) { const mapFunction = { "json": function(v) { return JSON.stringify(v, null, 2); }, "date": function(v) { return new Date(v).toLocaleString(); }, "raw": function(v) { return v; }, "duration": function(v) { return v +' seconds'; }, } return mapFunction[type](value) } ... const taskData = { "Type": ["raw", "type"], "Visit status": ["raw", "visit_status"], "Arguments": ["json", "arguments"], "Id": ["raw", "id"], "Backend id": ["raw", "backend_id"], "Scheduling date": ["date", "scheduled"], "Start date": ["date", "started"], "Termination date": ["date", "ended"], "Duration": ["duration", "duration"], "Executor": ["raw", "worker"], "Log": ["raw", "message"], }; for (const [title, [type, property]] of Object.entries(taskData)) { if (saveRequestTaskInfo.hasOwnProperty(property)) { saveRequestInfo.push({ key: title, value: formatValuePerType(saveRequestTaskInfo[property]) }); } ... ardumont: oh no... ;)
No idea if that would work, just thrown out there... just to show it'd be more… | |||||
Done Inline Actionssimpler, more readable. ardumont: simpler, more readable.
awesome, thanks. | |||||
Not Done Inline ActionsYour solution is quite equivalent, pick the one you prefer. anlambert: Your solution is quite equivalent, pick the one you prefer. | |||||
Not Done Inline ActionsLooks good to me. anlambert: Looks good to me. | |||||
Done Inline ActionsI kept my implementation but i reused the syntactic sugar on the lambdas ;). I somehow preferred it slightly to avoid repeating the lambdas per dict entry. In any case i like our new version is quite cleaner, it's more functional ;) Thanks for the heads up. ardumont: I kept my implementation but i reused the syntactic sugar on the lambdas ;).
I somehow… | |||||
if (saveRequestTaskInfo.message) { | |||||
saveRequestInfo.push({ | |||||
key: 'Task log', | |||||
value: saveRequestTaskInfo.message | |||||
}); | |||||
} | } | ||||
content = '<table class="table"><tbody>'; | content = '<table class="table"><tbody>'; | ||||
for (let info of saveRequestInfo) { | for (let info of saveRequestInfo) { | ||||
content += | content += | ||||
`<tr> | `<tr> | ||||
<th class="swh-metadata-table-row swh-metadata-table-key">${info.key}</th> | <th class="swh-metadata-table-row swh-metadata-table-key">${info.key}</th> | ||||
<td class="swh-metadata-table-row swh-metadata-table-value"> | <td class="swh-metadata-table-row swh-metadata-table-value"> | ||||
<pre>${info.value}</pre> | <pre>${info.value}</pre> | ||||
Show All 30 Lines |
Looking at this code I wrote at the time, I should have written it like that instead:
You should change it to remove the code duplication.