- Revamp decypharr arch \n
- Add callback_ur, download_folder to addContent API \n - Fix few bugs \n - More declarative UI keywords - Speed up repairs - Few other improvements/bug fixes
This commit is contained in:
@@ -245,43 +245,48 @@
|
||||
<!-- Step 5: Repair Configuration -->
|
||||
<div class="setup-step d-none" id="step5">
|
||||
<div class="section mb-5">
|
||||
<div class="row mb-2">
|
||||
<div class="row mb-3">
|
||||
<div class="col">
|
||||
<div class="form-check me-3 d-inline-block">
|
||||
<input type="checkbox" class="form-check-input" name="repair.enabled" id="repair.enabled">
|
||||
<label class="form-check-label" for="repair.enabled">Enable Repair</label>
|
||||
<label class="form-check-label" for="repair.enabled">Enable Scheduled Repair</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="repairCol" class="d-none">
|
||||
<div>
|
||||
<div class="row">
|
||||
<div class="col-md-4 mb-3">
|
||||
<label class="form-label" for="repair.interval">Interval</label>
|
||||
<label class="form-label" for="repair.interval">Scheduled Interval</label>
|
||||
<input type="text" class="form-control" name="repair.interval" id="repair.interval" placeholder="e.g., 24h">
|
||||
<small class="form-text text-muted">Interval for the repair process(e.g., 24h, 1d, 03:00, or a crontab)</small>
|
||||
</div>
|
||||
<div class="col-md-3 mb-3">
|
||||
<label class="form-label" for="repair.workers">Workers</label>
|
||||
<input type="text" class="form-control" name="repair.workers" id="repair.workers">
|
||||
<small class="form-text text-muted">Number of workers to use for the repair process</small>
|
||||
</div>
|
||||
<div class="col-md-5 mb-3">
|
||||
<label class="form-label" for="repair.zurg_url">Zurg URL</label>
|
||||
<input type="text" class="form-control" name="repair.zurg_url" id="repair.zurg_url" placeholder="http://zurg:9999">
|
||||
<small class="form-text text-muted">Speeds up the repair process by using Zurg</small>
|
||||
<small class="form-text text-muted">If you have Zurg running, you can use it to speed up the repair process</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-3 mb-3">
|
||||
<div class="col-md-4 mb-3">
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input" name="repair.use_webdav" id="repair.use_webdav">
|
||||
<label class="form-check-label" for="repair.use_webdav">Use Webdav</label>
|
||||
</div>
|
||||
<small class="form-text text-muted">Use Internal Webdav for repair(make sure webdav is enabled in the debrid section</small>
|
||||
</div>
|
||||
<div class="col-md-3 mb-3">
|
||||
<div class="col-md-4 mb-3">
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input" name="repair.run_on_start" id="repair.run_on_start">
|
||||
<label class="form-check-label" for="repair.run_on_start">Run on Start</label>
|
||||
</div>
|
||||
<small class="form-text text-muted">Run repair on startup</small>
|
||||
</div>
|
||||
<div class="col-md-3 mb-3">
|
||||
<div class="col-md-4 mb-3">
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input" name="repair.auto_process" id="repair.auto_process">
|
||||
<label class="form-check-label" for="repair.auto_process">Auto Process</label>
|
||||
@@ -340,7 +345,14 @@
|
||||
<small class="form-text text-muted">Rate limit for the debrid service. Confirm your debrid service rate limit</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-3">
|
||||
<div class="form-check me-3">
|
||||
<input type="checkbox" class="form-check-input useWebdav" name="debrid[${index}].use_webdav" id="debrid[${index}].use_webdav">
|
||||
<label class="form-check-label" for="debrid[${index}].use_webdav">Enable WebDav Server</label>
|
||||
</div>
|
||||
<small class="form-text text-muted">Create an internal webdav for this debrid</small>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-check me-3">
|
||||
<input type="checkbox" class="form-check-input" name="debrid[${index}].download_uncached" id="debrid[${index}].download_uncached">
|
||||
@@ -348,13 +360,6 @@
|
||||
</div>
|
||||
<small class="form-text text-muted">Download uncached files from the debrid service</small>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-check me-3">
|
||||
<input type="checkbox" class="form-check-input" name="debrid[${index}].check_cached" id="debrid[${index}].check_cached">
|
||||
<label class="form-check-label" for="debrid[${index}].check_cached" disabled>Check Cached</label>
|
||||
</div>
|
||||
<small class="form-text text-muted">Check if the file is cached before downloading(Disabled)</small>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-check me-3">
|
||||
<input type="checkbox" class="form-check-input" name="debrid[${index}].add_samples" id="debrid[${index}].add_samples">
|
||||
@@ -369,16 +374,10 @@
|
||||
</div>
|
||||
<small class="form-text text-muted">Preprocess RARed torrents to allow reading the files inside</small>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-check me-3">
|
||||
<input type="checkbox" class="form-check-input useWebdav" name="debrid[${index}].use_webdav" id="debrid[${index}].use_webdav">
|
||||
<label class="form-check-label" for="debrid[${index}].use_webdav">Enable WebDav Server</label>
|
||||
</div>
|
||||
<small class="form-text text-muted">Create an internal webdav for this debrid</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="webdav d-none">
|
||||
<h6 class="pb-2">Webdav</h6>
|
||||
<div class="webdav d-none mt-1">
|
||||
<hr/>
|
||||
<h6 class="pb-2">Webdav Settings</h6>
|
||||
<div class="row mt-3">
|
||||
<div class="col-md-3 mb-3">
|
||||
<label class="form-label" for="debrid[${index}].torrents_refresh_interval">Torrents Refresh Interval</label>
|
||||
@@ -441,12 +440,12 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="col mt-3">
|
||||
<h6 class="pb-2">Custom Folders</h6>
|
||||
<div class="col">
|
||||
<h6 class="pb-2">Virtual Folders</h6>
|
||||
<div class="col-12">
|
||||
<p class="text-muted small">Create virtual directories with filters to organize your content</p>
|
||||
<div class="directories-container" id="debrid[${index}].directories">
|
||||
<!-- Dynamic directories will be added here -->
|
||||
|
||||
</div>
|
||||
<button type="button" class="btn btn-secondary mt-2 webdav-field" onclick="addDirectory(${index});">
|
||||
<i class="bi bi-plus"></i> Add Directory
|
||||
@@ -842,9 +841,6 @@
|
||||
|
||||
// Load Repair config
|
||||
if (config.repair) {
|
||||
if (config.repair.enabled) {
|
||||
document.getElementById('repairCol').classList.remove('d-none');
|
||||
}
|
||||
Object.entries(config.repair).forEach(([key, value]) => {
|
||||
const input = document.querySelector(`[name="repair.${key}"]`);
|
||||
if (input) {
|
||||
@@ -921,14 +917,6 @@
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on('change', 'input[name="repair.enabled"]', function() {
|
||||
if (this.checked) {
|
||||
$('#repairCol').removeClass('d-none');
|
||||
} else {
|
||||
$('#repairCol').addClass('d-none');
|
||||
}
|
||||
});
|
||||
|
||||
async function saveConfig(e) {
|
||||
const submitButton = e.target.querySelector('button[type="submit"]');
|
||||
submitButton.disabled = true;
|
||||
@@ -1072,7 +1060,7 @@
|
||||
debrids: [],
|
||||
qbittorrent: {
|
||||
download_folder: document.querySelector('[name="qbit.download_folder"]').value,
|
||||
refresh_interval: parseInt(document.querySelector('[name="qbit.refresh_interval"]').value || '0', 10),
|
||||
refresh_interval: parseInt(document.querySelector('[name="qbit.refresh_interval"]').value, 10),
|
||||
max_downloads: parseInt(document.querySelector('[name="qbit.max_downloads"]').value || '0', 5),
|
||||
skip_pre_cache: document.querySelector('[name="qbit.skip_pre_cache"]').checked
|
||||
},
|
||||
@@ -1082,6 +1070,7 @@
|
||||
interval: document.querySelector('[name="repair.interval"]').value,
|
||||
run_on_start: document.querySelector('[name="repair.run_on_start"]').checked,
|
||||
zurg_url: document.querySelector('[name="repair.zurg_url"]').value,
|
||||
workers: parseInt(document.querySelector('[name="repair.workers"]').value),
|
||||
use_webdav: document.querySelector('[name="repair.use_webdav"]').checked,
|
||||
auto_process: document.querySelector('[name="repair.auto_process"]').checked
|
||||
}
|
||||
@@ -1098,7 +1087,6 @@
|
||||
folder: document.querySelector(`[name="debrid[${i}].folder"]`).value,
|
||||
rate_limit: document.querySelector(`[name="debrid[${i}].rate_limit"]`).value,
|
||||
download_uncached: document.querySelector(`[name="debrid[${i}].download_uncached"]`).checked,
|
||||
check_cached: document.querySelector(`[name="debrid[${i}].check_cached"]`).checked,
|
||||
unpack_rar: document.querySelector(`[name="debrid[${i}].unpack_rar"]`).checked,
|
||||
add_samples: document.querySelector(`[name="debrid[${i}].add_samples"]`).checked,
|
||||
use_webdav: document.querySelector(`[name="debrid[${i}].use_webdav"]`).checked
|
||||
|
||||
@@ -17,11 +17,33 @@
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="category" class="form-label">Enter Category</label>
|
||||
<input type="text" class="form-control" id="category" name="arr" placeholder="Enter Category (e.g sonarr, radarr, radarr4k)">
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-6">
|
||||
<label for="downloadFolder" class="form-label">Download Folder</label>
|
||||
<input type="text" class="form-control" id="downloadFolder" name="downloadFolder" placeholder="Enter Download Folder (e.g /downloads/torrents)">
|
||||
<small class="text-muted">Default is your qbittorent download_folder</small>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label for="arr" class="form-label">Arr (if any)</label>
|
||||
<input type="text" class="form-control" id="arr" name="arr" placeholder="Enter Category (e.g sonarr, radarr, radarr4k)">
|
||||
<small class="text-muted">Optional, leave empty if not using Arr</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{ if .HasMultiDebrid }}
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-6">
|
||||
<label for="debrid" class="form-label">Select Debrid</label>
|
||||
<select class="form-select" id="debrid" name="debrid">
|
||||
{{ range $index, $debrid := .Debrids }}
|
||||
<option value="{{ $debrid }}" {{ if eq $index 0 }}selected{{end}}>{{ $debrid }}</option>
|
||||
{{ end }}
|
||||
</select>
|
||||
<small class="text-muted">Select a debrid service to use for this download</small>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-2 mb-3">
|
||||
<div class="form-check d-inline-block me-3">
|
||||
@@ -48,23 +70,27 @@
|
||||
</div>
|
||||
|
||||
<script>
|
||||
let downloadFolder = '{{ .DownloadFolder }}';
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const loadSavedDownloadOptions = () => {
|
||||
const savedCategory = localStorage.getItem('downloadCategory');
|
||||
const savedSymlink = localStorage.getItem('downloadSymlink');
|
||||
const savedDownloadUncached = localStorage.getItem('downloadUncached');
|
||||
document.getElementById('category').value = savedCategory || '';
|
||||
document.getElementById('arr').value = savedCategory || '';
|
||||
document.getElementById('isSymlink').checked = savedSymlink === 'true';
|
||||
document.getElementById('downloadUncached').checked = savedDownloadUncached === 'true';
|
||||
document.getElementById('downloadFolder').value = localStorage.getItem('downloadFolder') || downloadFolder || '';
|
||||
};
|
||||
|
||||
const saveCurrentDownloadOptions = () => {
|
||||
const category = document.getElementById('category').value;
|
||||
const arr = document.getElementById('arr').value;
|
||||
const isSymlink = document.getElementById('isSymlink').checked;
|
||||
const downloadUncached = document.getElementById('downloadUncached').checked;
|
||||
localStorage.setItem('downloadCategory', category);
|
||||
const downloadFolder = document.getElementById('downloadFolder').value;
|
||||
localStorage.setItem('downloadCategory', arr);
|
||||
localStorage.setItem('downloadSymlink', isSymlink.toString());
|
||||
localStorage.setItem('downloadUncached', downloadUncached.toString());
|
||||
localStorage.setItem('downloadFolder', downloadFolder);
|
||||
};
|
||||
|
||||
// Load the last used download options from local storage
|
||||
@@ -108,9 +134,11 @@
|
||||
return;
|
||||
}
|
||||
|
||||
formData.append('arr', document.getElementById('category').value);
|
||||
formData.append('arr', document.getElementById('arr').value);
|
||||
formData.append('downloadFolder', document.getElementById('downloadFolder').value);
|
||||
formData.append('notSymlink', document.getElementById('isSymlink').checked);
|
||||
formData.append('downloadUncached', document.getElementById('downloadUncached').checked);
|
||||
formData.append('debrid', document.getElementById('debrid') ? document.getElementById('debrid').value : '');
|
||||
|
||||
const response = await fetcher('/api/add', {
|
||||
method: 'POST',
|
||||
@@ -139,7 +167,7 @@
|
||||
});
|
||||
|
||||
// Save the download options to local storage when they change
|
||||
document.getElementById('category').addEventListener('change', saveCurrentDownloadOptions);
|
||||
document.getElementById('arr').addEventListener('change', saveCurrentDownloadOptions);
|
||||
document.getElementById('isSymlink').addEventListener('change', saveCurrentDownloadOptions);
|
||||
|
||||
// Read the URL parameters for a magnet link and add it to the download queue if found
|
||||
|
||||
@@ -129,11 +129,11 @@
|
||||
<td>${torrent.debrid || 'None'}</td>
|
||||
<td><span class="badge ${getStateColor(torrent.state)}">${torrent.state}</span></td>
|
||||
<td>
|
||||
<button class="btn btn-sm btn-outline-danger" onclick="deleteTorrent('${torrent.hash}', '${torrent.category}', false)">
|
||||
<button class="btn btn-sm btn-outline-danger" onclick="deleteTorrent('${torrent.hash}', '${torrent.category || ''}', false)">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>
|
||||
${torrent.debrid && torrent.id ? `
|
||||
<button class="btn btn-sm btn-outline-danger" onclick="deleteTorrent('${torrent.hash}', '${torrent.category}', true)">
|
||||
<button class="btn btn-sm btn-outline-danger" onclick="deleteTorrent('${torrent.hash}', '${torrent.category || ''}', true)">
|
||||
<i class="bi bi-trash"></i> Remove from Debrid
|
||||
</button>
|
||||
` : ''}
|
||||
@@ -485,7 +485,7 @@
|
||||
}
|
||||
},
|
||||
'delete': async (torrent) => {
|
||||
await deleteTorrent(torrent.hash);
|
||||
await deleteTorrent(torrent.hash, torrent.category || '', false);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -36,6 +36,22 @@
|
||||
background-color: var(--bg-color);
|
||||
color: var(--text-color);
|
||||
transition: background-color 0.3s ease, color 0.3s ease;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
footer {
|
||||
background-color: var(--bg-color);
|
||||
border-top: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
footer a {
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
footer a:hover {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.navbar {
|
||||
@@ -193,6 +209,20 @@
|
||||
{{ else }}
|
||||
{{ end }}
|
||||
|
||||
<footer class="mt-auto py-2 text-center border-top">
|
||||
<div class="container">
|
||||
<small class="text-muted">
|
||||
<a href="https://github.com/sirrobot01/decypharr" target="_blank" class="text-decoration-none me-3">
|
||||
<i class="bi bi-github me-1"></i>GitHub
|
||||
</a>
|
||||
<a href="https://sirrobot01.github.io/decypharr" target="_blank" class="text-decoration-none">
|
||||
<i class="bi bi-book me-1"></i>Documentation
|
||||
</a>
|
||||
</small>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
|
||||
|
||||
@@ -143,6 +143,9 @@
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||
<button type="button" class="btn btn-primary" id="processJobBtn">Process Items</button>
|
||||
<button type="button" class="btn btn-warning d-none" id="stopJobBtn">
|
||||
<i class="bi bi-stop-fill me-1"></i>Stop Job
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -218,6 +221,27 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Return status text and class based on job status
|
||||
function getStatus(status) {
|
||||
switch (status) {
|
||||
case 'started':
|
||||
return {text: 'In Progress', class: 'text-primary'};
|
||||
case 'failed':
|
||||
return {text: 'Failed', class: 'text-danger'};
|
||||
case 'completed':
|
||||
return {text: 'Completed', class: 'text-success'};
|
||||
case 'pending':
|
||||
return {text: 'Pending', class: 'text-warning'};
|
||||
case 'cancelled':
|
||||
return {text: 'Cancelled', class: 'text-secondary'};
|
||||
case 'processing':
|
||||
return {text: 'Processing', class: 'text-info'};
|
||||
default:
|
||||
// Return status in title case if unknown
|
||||
return {text: status.charAt(0).toUpperCase() + status.slice(1), class: 'text-secondary'};
|
||||
}
|
||||
}
|
||||
|
||||
// Render jobs table with pagination
|
||||
function renderJobsTable(page) {
|
||||
const tableBody = document.getElementById('jobsTableBody');
|
||||
@@ -254,24 +278,10 @@
|
||||
const formattedDate = startedDate.toLocaleString();
|
||||
|
||||
// Determine status
|
||||
let status = 'In Progress';
|
||||
let statusClass = 'text-primary';
|
||||
let status = getStatus(job.status);
|
||||
let canDelete = job.status !== "started";
|
||||
let totalItems = job.broken_items ? Object.values(job.broken_items).reduce((sum, arr) => sum + arr.length, 0) : 0;
|
||||
|
||||
if (job.status === 'failed') {
|
||||
status = 'Failed';
|
||||
statusClass = 'text-danger';
|
||||
} else if (job.status === 'completed') {
|
||||
status = 'Completed';
|
||||
statusClass = 'text-success';
|
||||
} else if (job.status === 'pending') {
|
||||
status = 'Pending';
|
||||
statusClass = 'text-warning';
|
||||
} else if (job.status === "processing") {
|
||||
status = 'Processing';
|
||||
statusClass = 'text-info';
|
||||
}
|
||||
|
||||
row.innerHTML = `
|
||||
<td>
|
||||
@@ -283,25 +293,31 @@
|
||||
<td><a href="#" class="text-link view-job" data-id="${job.id}"><small>${job.id.substring(0, 8)}</small></a></td>
|
||||
<td>${job.arrs.join(', ')}</td>
|
||||
<td><small>${formattedDate}</small></td>
|
||||
<td><span class="${statusClass}">${status}</span></td>
|
||||
<td><span class="${status.class}">${status.text}</span></td>
|
||||
<td>${totalItems}</td>
|
||||
<td>
|
||||
${job.status === "pending" ?
|
||||
`<button class="btn btn-sm btn-primary process-job" data-id="${job.id}">
|
||||
<i class="bi bi-play-fill"></i> Process
|
||||
`<button class="btn btn-sm btn-primary process-job" data-id="${job.id}">
|
||||
<i class="bi bi-play-fill"></i> Process
|
||||
</button>` :
|
||||
`<button class="btn btn-sm btn-primary" disabled>
|
||||
<i class="bi bi-eye"></i> Process
|
||||
`<button class="btn btn-sm btn-primary" disabled>
|
||||
<i class="bi bi-eye"></i> Process
|
||||
</button>`
|
||||
}
|
||||
}
|
||||
${(job.status === "started" || job.status === "processing") ?
|
||||
`<button class="btn btn-sm btn-warning stop-job" data-id="${job.id}">
|
||||
<i class="bi bi-stop-fill"></i> Stop
|
||||
</button>` :
|
||||
''
|
||||
}
|
||||
${canDelete ?
|
||||
`<button class="btn btn-sm btn-danger delete-job" data-id="${job.id}">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>` :
|
||||
`<button class="btn btn-sm btn-danger" disabled>
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>`
|
||||
}
|
||||
`<button class="btn btn-sm btn-danger delete-job" data-id="${job.id}">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>` :
|
||||
`<button class="btn btn-sm btn-danger" disabled>
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>`
|
||||
}
|
||||
</td>
|
||||
`;
|
||||
|
||||
@@ -370,6 +386,13 @@
|
||||
viewJobDetails(jobId);
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelectorAll('.stop-job').forEach(button => {
|
||||
button.addEventListener('click', (e) => {
|
||||
const jobId = e.currentTarget.dataset.id;
|
||||
stopJob(jobId);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
document.getElementById('selectAllJobs').addEventListener('change', function() {
|
||||
@@ -456,6 +479,25 @@
|
||||
}
|
||||
}
|
||||
|
||||
async function stopJob(jobId) {
|
||||
if (confirm('Are you sure you want to stop this job?')) {
|
||||
try {
|
||||
const response = await fetcher(`/api/repair/jobs/${jobId}/stop`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) throw new Error(await response.text());
|
||||
createToast('Job stop requested successfully');
|
||||
await loadJobs(currentPage); // Refresh the jobs list
|
||||
} catch (error) {
|
||||
createToast(`Error stopping job: ${error.message}`, 'error');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// View job details function
|
||||
function viewJobDetails(jobId) {
|
||||
// Find the job
|
||||
@@ -477,24 +519,9 @@
|
||||
}
|
||||
|
||||
// Set status with color
|
||||
let status = 'In Progress';
|
||||
let statusClass = 'text-primary';
|
||||
let status = getStatus(job.status);
|
||||
|
||||
if (job.status === 'failed') {
|
||||
status = 'Failed';
|
||||
statusClass = 'text-danger';
|
||||
} else if (job.status === 'completed') {
|
||||
status = 'Completed';
|
||||
statusClass = 'text-success';
|
||||
} else if (job.status === 'pending') {
|
||||
status = 'Pending';
|
||||
statusClass = 'text-warning';
|
||||
} else if (job.status === "processing") {
|
||||
status = 'Processing';
|
||||
statusClass = 'text-info';
|
||||
}
|
||||
|
||||
document.getElementById('modalJobStatus').innerHTML = `<span class="${statusClass}">${status}</span>`;
|
||||
document.getElementById('modalJobStatus').innerHTML = `<span class="${status.class}">${status.text}</span>`;
|
||||
|
||||
// Set other job details
|
||||
document.getElementById('modalJobArrs').textContent = job.arrs.join(', ');
|
||||
@@ -524,6 +551,19 @@
|
||||
processBtn.classList.add('d-none');
|
||||
}
|
||||
|
||||
// Stop button visibility
|
||||
const stopBtn = document.getElementById('stopJobBtn'); // You'll need to add this button to the HTML
|
||||
if (job.status === 'started' || job.status === 'processing') {
|
||||
stopBtn.classList.remove('d-none');
|
||||
stopBtn.onclick = () => {
|
||||
stopJob(job.id);
|
||||
const modal = bootstrap.Modal.getInstance(document.getElementById('jobDetailsModal'));
|
||||
modal.hide();
|
||||
};
|
||||
} else {
|
||||
stopBtn.classList.add('d-none');
|
||||
}
|
||||
|
||||
// Populate broken items table
|
||||
const brokenItemsTableBody = document.getElementById('brokenItemsTableBody');
|
||||
const noBrokenItemsMessage = document.getElementById('noBrokenItemsMessage');
|
||||
|
||||
Reference in New Issue
Block a user