@@ -2124,6 +2124,24 @@ async function pruneResource(kind) {
|
||||
});
|
||||
if (!confirmed) return;
|
||||
|
||||
if (typeof window.peardockOps?.pruneJob === 'function') {
|
||||
try {
|
||||
await window.peardockOps.pruneJob({
|
||||
kind,
|
||||
label: conf.label,
|
||||
method: conf.method,
|
||||
});
|
||||
if (kind === 'containers') sendCommand('listContainers');
|
||||
if (kind === 'images' || kind === 'builder') sendCommand('listImages');
|
||||
if (kind === 'networks') sendCommand('listNetworks');
|
||||
if (kind === 'volumes') sendCommand('listVolumes');
|
||||
sendCommand('getSystemDf');
|
||||
} catch (err) {
|
||||
if (!err?.viaJob) showAlert('danger', err.message || 'Prune failed');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
showStatusIndicator(`Pruning ${conf.label}…`);
|
||||
try {
|
||||
const response = await sendCommand(conf.method, {});
|
||||
@@ -2177,6 +2195,24 @@ async function systemPrune(opts = {}) {
|
||||
});
|
||||
if (!confirmed) return;
|
||||
|
||||
if (typeof window.peardockOps?.pruneJob === 'function') {
|
||||
try {
|
||||
await window.peardockOps.pruneJob({
|
||||
kind: 'system',
|
||||
label: volumes ? 'system (+ volumes)' : 'system',
|
||||
method: Methods.systemPrune || 'systemPrune',
|
||||
args: { volumes, all: false },
|
||||
});
|
||||
sendCommand('listContainers');
|
||||
sendCommand('listImages');
|
||||
sendCommand('listNetworks');
|
||||
sendCommand('getSystemDf');
|
||||
} catch (err) {
|
||||
if (!err?.viaJob) showAlert('danger', err.message || 'System prune failed');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
showStatusIndicator('Running docker system prune…');
|
||||
try {
|
||||
const response = await sendCommand('systemPrune', { volumes, all: false });
|
||||
@@ -2329,6 +2365,20 @@ async function recreateContainerAction(container) {
|
||||
});
|
||||
if (!confirmed) return;
|
||||
|
||||
if (typeof window.peardockOps?.recreateContainersJob === 'function') {
|
||||
try {
|
||||
await window.peardockOps.recreateContainersJob({
|
||||
ids: [container.Id],
|
||||
names: [name],
|
||||
start: true,
|
||||
});
|
||||
sendCommand('listContainers');
|
||||
} catch (err) {
|
||||
if (!err?.viaJob) showAlert('danger', err.message || 'Recreate failed');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
showStatusIndicator(`Recreating ${name}…`);
|
||||
try {
|
||||
const response = await sendCommand('recreateContainer', {
|
||||
@@ -3513,6 +3563,18 @@ function renderStacks(stacks) {
|
||||
}
|
||||
});
|
||||
if (!confirmed) return;
|
||||
|
||||
if (typeof window.peardockOps?.removeStackJob === 'function') {
|
||||
try {
|
||||
await window.peardockOps.removeStackJob({ stackName });
|
||||
loadStacks();
|
||||
} catch (error) {
|
||||
if (!error?.viaJob) {
|
||||
showAlert('danger', error.message || 'Failed to remove stack');
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
showStatusIndicator(`Removing stack "${stackName}"...`);
|
||||
sendCommand('removeStack', { stackName });
|
||||
@@ -3827,6 +3889,28 @@ function setupBuildImageHandler() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof window.peardockOps?.buildImageJob === 'function') {
|
||||
try {
|
||||
const modal = bootstrap.Modal.getInstance(document.getElementById('buildImageModal'));
|
||||
if (modal) modal.hide();
|
||||
await window.peardockOps.buildImageJob({
|
||||
tag,
|
||||
dockerfile,
|
||||
buildFn: async () => {
|
||||
sendCommand('buildImage', { tag, dockerfile });
|
||||
return waitForPeerResponse('Image built successfully');
|
||||
},
|
||||
});
|
||||
buildImageForm.reset();
|
||||
sendCommand('listImages');
|
||||
} catch (error) {
|
||||
if (!error?.viaJob) {
|
||||
showAlert('danger', error.message || 'Failed to build image');
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
showStatusIndicator(`Building image "${tag}"...`);
|
||||
sendCommand('buildImage', { tag, dockerfile });
|
||||
|
||||
@@ -3957,6 +4041,19 @@ function createVolume() {
|
||||
|
||||
const modal = bootstrap.Modal.getInstance(document.getElementById('createVolumeModal'));
|
||||
if (modal) modal.hide();
|
||||
|
||||
if (typeof window.peardockOps?.createVolumeJob === 'function') {
|
||||
window.peardockOps
|
||||
.createVolumeJob({ name, driver: driver || undefined })
|
||||
.then(() => {
|
||||
if (typeof loadVolumes === 'function') loadVolumes();
|
||||
else sendCommand('listVolumes');
|
||||
})
|
||||
.catch((err) => {
|
||||
if (!err?.viaJob) showAlert('danger', err.message || 'Failed to create volume');
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
showStatusIndicator(`Creating volume "${name}"...`);
|
||||
sendCommand('createVolume', { name, driver });
|
||||
@@ -4303,6 +4400,41 @@ async function runContainerDetailAction(action, container, btn) {
|
||||
if (!spec) return;
|
||||
|
||||
if (btn) btn.disabled = true;
|
||||
|
||||
if (typeof window.peardockOps?.containerActionJob === 'function') {
|
||||
try {
|
||||
await window.peardockOps.containerActionJob({
|
||||
action,
|
||||
id,
|
||||
name,
|
||||
force: true,
|
||||
});
|
||||
sendCommand('listContainers');
|
||||
if (action === 'remove') {
|
||||
currentContainerDetails = null;
|
||||
navigateToView('containers');
|
||||
return;
|
||||
}
|
||||
const nextState =
|
||||
action === 'start' || action === 'resume' || action === 'restart'
|
||||
? 'running'
|
||||
: action === 'stop' || action === 'kill'
|
||||
? 'exited'
|
||||
: action === 'pause'
|
||||
? 'paused'
|
||||
: container.State;
|
||||
const updated = { ...container, State: nextState, Status: nextState };
|
||||
currentContainerDetails = updated;
|
||||
if (typeof window !== 'undefined') window.currentContainerDetails = updated;
|
||||
updateContainerDetailsActions(updated);
|
||||
} catch (err) {
|
||||
if (!err?.viaJob) presentError(err, spec.method, { showAlert });
|
||||
} finally {
|
||||
if (btn) btn.disabled = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
showStatusIndicator(`${spec.label}ing ${name}…`);
|
||||
try {
|
||||
const payload =
|
||||
@@ -7145,6 +7277,29 @@ async function runBulkContainerOperation(operation, meta) {
|
||||
if (!ok) return;
|
||||
}
|
||||
|
||||
if (typeof window.peardockOps?.bulkContainerJob === 'function') {
|
||||
try {
|
||||
const names = selected.map((id) => {
|
||||
const row = document.querySelector(`.container-checkbox[value="${id}"]`);
|
||||
const tr = row?.closest('tr');
|
||||
const nameCell = tr?.querySelector('[data-container-name], .container-name, td:nth-child(2)');
|
||||
return (nameCell?.textContent || '').trim().replace(/^\//, '') || id.slice(0, 12);
|
||||
});
|
||||
await window.peardockOps.bulkContainerJob({
|
||||
operation,
|
||||
label: meta.label,
|
||||
containerIds: selected,
|
||||
names,
|
||||
force: true,
|
||||
});
|
||||
clearContainerSelection();
|
||||
sendCommand('listContainers');
|
||||
} catch (err) {
|
||||
if (!err?.viaJob) presentError(err, 'bulkContainerOperation', { showAlert });
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
showStatusIndicator(`${meta.label}ing ${selected.length} container(s)…`);
|
||||
try {
|
||||
const res = await manager.request(Methods.bulkContainerOperation, {
|
||||
@@ -7300,6 +7455,20 @@ async function bulkRecreateContainers() {
|
||||
}
|
||||
if (!ok) return;
|
||||
|
||||
if (typeof window.peardockOps?.recreateContainersJob === 'function') {
|
||||
try {
|
||||
await window.peardockOps.recreateContainersJob({
|
||||
ids: selected,
|
||||
start: true,
|
||||
});
|
||||
clearContainerSelection();
|
||||
sendCommand('listContainers');
|
||||
} catch (err) {
|
||||
if (!err?.viaJob) presentError(err, 'recreateContainer', { showAlert });
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
showStatusIndicator(`Recreating ${selected.length} container(s)…`);
|
||||
let successCount = 0;
|
||||
let failCount = 0;
|
||||
@@ -7361,6 +7530,20 @@ async function bulkRemoveImages() {
|
||||
}
|
||||
});
|
||||
if (!confirmed) return;
|
||||
|
||||
if (typeof window.peardockOps?.removeImagesJob === 'function') {
|
||||
try {
|
||||
await window.peardockOps.removeImagesJob({
|
||||
ids: selected,
|
||||
force: true,
|
||||
});
|
||||
clearImageSelection();
|
||||
setTimeout(() => loadImages(), 400);
|
||||
} catch (err) {
|
||||
if (!err?.viaJob) showAlert('danger', err.message || 'Failed to remove images');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
showStatusIndicator(`Removing ${selected.length} image(s)...`);
|
||||
let completed = 0;
|
||||
@@ -10739,66 +10922,66 @@ function addActionListeners(row, container) {
|
||||
const killBtn = row.querySelector('.action-kill');
|
||||
const topBtn = row.querySelector('.action-top');
|
||||
|
||||
// Start Button (primary row actions only — more actions use the modal)
|
||||
if (!startBtn) return;
|
||||
startBtn.addEventListener('click', async () => {
|
||||
showStatusIndicator(`Starting container "${container.Names[0]}"...`);
|
||||
sendCommand('startContainer', { id: container.Id });
|
||||
|
||||
const expectedMessageFragment = `Container ${container.Id} started`;
|
||||
|
||||
try {
|
||||
const response = await waitForPeerResponse(expectedMessageFragment);
|
||||
console.log('[DEBUG] Start container response:', response);
|
||||
|
||||
showAlert('success', response.message);
|
||||
|
||||
// Refresh the container list to update states
|
||||
sendCommand('listContainers');
|
||||
|
||||
// Restart stats interval
|
||||
startStatsInterval();
|
||||
} catch (error) {
|
||||
console.error('[ERROR] Failed to start container:', error.message);
|
||||
showAlert('danger', error.message || 'Failed to start container.');
|
||||
} finally {
|
||||
console.log('[DEBUG] Hiding status indicator in startBtn finally block');
|
||||
hideStatusIndicator();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if (stopBtn) {
|
||||
stopBtn.addEventListener('click', async () => {
|
||||
showStatusIndicator(`Stopping container "${container.Names[0]}"...`);
|
||||
sendCommand('stopContainer', { id: container.Id });
|
||||
|
||||
const expectedMessageFragment = `Container ${container.Id} stopped`;
|
||||
|
||||
const cname = (container.Names?.[0] || '').replace(/^\//, '') || container.Id.slice(0, 12);
|
||||
/** @param {string} action */
|
||||
async function runRowContainerAction(action) {
|
||||
if (typeof window.peardockOps?.containerActionJob === 'function') {
|
||||
try {
|
||||
const response = await waitForPeerResponse(expectedMessageFragment);
|
||||
console.log('[DEBUG] Stop container response:', response);
|
||||
|
||||
showAlert('success', response.message);
|
||||
|
||||
// Refresh the container list to update states
|
||||
await window.peardockOps.containerActionJob({
|
||||
action,
|
||||
id: container.Id,
|
||||
name: cname,
|
||||
force: true,
|
||||
});
|
||||
sendCommand('listContainers');
|
||||
|
||||
// Restart stats interval
|
||||
startStatsInterval();
|
||||
} catch (error) {
|
||||
console.error('[ERROR] Failed to stop container:', error.message);
|
||||
showAlert('danger', error.message || 'Failed to stop container.');
|
||||
} finally {
|
||||
console.log('[DEBUG] Hiding status indicator in stopBtn finally block');
|
||||
hideStatusIndicator();
|
||||
if (!error?.viaJob) {
|
||||
showAlert('danger', error.message || `Failed to ${action} container.`);
|
||||
}
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
// Legacy fallback
|
||||
const methodMap = {
|
||||
start: 'startContainer',
|
||||
stop: 'stopContainer',
|
||||
restart: 'restartContainer',
|
||||
kill: 'killContainer',
|
||||
pause: 'pauseContainer',
|
||||
resume: 'unpauseContainer',
|
||||
};
|
||||
const method = methodMap[action];
|
||||
if (!method) return;
|
||||
showStatusIndicator(`${action} container "${cname}"…`);
|
||||
sendCommand(method, { id: container.Id });
|
||||
try {
|
||||
const response = await waitForPeerResponse(`Container ${container.Id}`);
|
||||
showAlert('success', response.message);
|
||||
sendCommand('listContainers');
|
||||
startStatsInterval();
|
||||
} catch (error) {
|
||||
showAlert('danger', error.message || `Failed to ${action} container.`);
|
||||
} finally {
|
||||
hideStatusIndicator();
|
||||
}
|
||||
}
|
||||
|
||||
// Start Button (primary row actions only — more actions use the modal)
|
||||
if (!startBtn) return;
|
||||
startBtn.addEventListener('click', () => runRowContainerAction('start'));
|
||||
|
||||
if (stopBtn) {
|
||||
stopBtn.addEventListener('click', () => runRowContainerAction('stop'));
|
||||
}
|
||||
|
||||
// Restart / kill / pause / etc. live in the more-actions modal when not on the row
|
||||
if (restartBtn) {
|
||||
restartBtn.addEventListener('click', async () => {
|
||||
if (typeof window.peardockOps?.containerActionJob === 'function') {
|
||||
await runRowContainerAction('restart');
|
||||
return;
|
||||
}
|
||||
showStatusIndicator(`Restarting container "${container.Names[0]}"...`);
|
||||
sendCommand('restartContainer', { id: container.Id });
|
||||
|
||||
|
||||
Reference in New Issue
Block a user