Add dashboard IPs/restart/connections, SMB read-only and recycle bin
Dashboard: - Server IPs card showing all non-loopback IPv4 interfaces - Restart buttons next to smbd/nfsd status dots (POST /api/service/<name>/restart) - Active SMB connections table (smbstatus -b parsed in backend) SMB edit modal: - Read only toggle (writable vs read only in smb.conf) - Recycle Bin toggle (vfs objects = recycle, files go to .recycle folder) Docs: PLANNING.md phase 3.5, README recycle bin + read-only, CLAUDE.md JS overview Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
1810d60d21
commit
1be6a05cef
7 files changed
+171
-21
No files matched your search
+15
-5
@@ -187,10 +187,18 @@ async function openEditModal(type, share) {
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-check ms-1 mb-3">
|
||||
<div class="form-check ms-1 mb-1">
|
||||
<input type="checkbox" id="editReadOnly" class="form-check-input" ${share.read_only ? 'checked' : ''}>
|
||||
<label class="form-check-label" for="editReadOnly" style="color:var(--muted)">Read only — clients cannot write</label>
|
||||
</div>
|
||||
<div class="form-check ms-1 mb-1">
|
||||
<input type="checkbox" id="editGuestOk" class="form-check-input" ${share.guest_ok ? 'checked' : ''}>
|
||||
<label class="form-check-label" for="editGuestOk" style="color:var(--muted)">Guest OK — allow access without a password</label>
|
||||
</div>
|
||||
<div class="form-check ms-1 mb-3">
|
||||
<input type="checkbox" id="editRecycleBin" class="form-check-input" ${share.recycle_bin ? 'checked' : ''}>
|
||||
<label class="form-check-label" for="editRecycleBin" style="color:var(--muted)">Recycle Bin — deleted files go to <code>.recycle</code> instead of being gone</label>
|
||||
</div>
|
||||
${permSection}`;
|
||||
} else {
|
||||
const isRo = /\(ro[,)]/.test(share.clients);
|
||||
@@ -231,12 +239,14 @@ async function submitEdit() {
|
||||
const name = document.getElementById('editName').value.trim();
|
||||
const path = document.getElementById('editPath').value.trim();
|
||||
const validUsers = document.getElementById('editUsers').value.trim();
|
||||
const forceUser = document.getElementById('editForceUser').value;
|
||||
const forceGroup = document.getElementById('editForceGroup').value;
|
||||
const guestOk = document.getElementById('editGuestOk').checked;
|
||||
const forceUser = document.getElementById('editForceUser').value;
|
||||
const forceGroup = document.getElementById('editForceGroup').value;
|
||||
const guestOk = document.getElementById('editGuestOk').checked;
|
||||
const readOnly = document.getElementById('editReadOnly').checked;
|
||||
const recycleBin = document.getElementById('editRecycleBin').checked;
|
||||
res = await apiFetch(`/api/share/smb/${encodeURIComponent(ctx.original.name)}`, {
|
||||
method: 'PATCH', headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({name, path, validUsers, forceUser, forceGroup, guestOk}),
|
||||
body: JSON.stringify({name, path, validUsers, forceUser, forceGroup, guestOk, readOnly, recycleBin}),
|
||||
});
|
||||
} else {
|
||||
const clients = document.getElementById('editClients').value.trim();
|
||||
|
||||
Reference in new issue
Block a user