diff --git a/index.html b/index.html
index 474fe162..dc0d2f75 100644
--- a/index.html
+++ b/index.html
@@ -175,6 +175,17 @@
.submit-branches-btn:hover {
background-color: #1976d2;
}
+ .path-btn {
+ background-color: #1565c0;
+ color: white;
+ border: none;
+ padding: 5px 10px;
+ cursor: pointer;
+ margin-right: 5px;
+ }
+ .path-btn:hover {
+ background-color: #1976d2;
+ }
.mount-list-item {
padding: 10px;
cursor: pointer;
@@ -251,137 +262,137 @@
function getMounts() {
return g_mounts;
}
- function loadMounts() {
- fetch('/mounts')
- .then(r => {
- if (!r.ok) throw new Error('Failed to fetch mounts');
- return r.json();
- })
- .then(data => {
- g_mounts = data;
- populateMountSelect('mount-select-advanced', function() {
- loadAllForMount(this.value);
- });
- populateMountSelect('mount-select-branches', function() {
- loadAllForMount(this.value);
- });
- if (g_mounts.length > 0) {
- loadAllForMount(g_mounts[0]);
- }
- })
- .catch(err => console.error('Error loading mounts:', err));
- }
- function fetchBranches(mount) {
- return fetch('/kvs/branches?mount=' + encodeURIComponent(mount))
- .then(r => {
- if (!r.ok) throw new Error('Failed to fetch branches');
- return r.json();
- });
- }
- function fetchKV(mount) {
- return fetch('/kvs?mount=' + encodeURIComponent(mount))
- .then(r => {
- if (!r.ok) throw new Error('Failed to fetch kvs');
- return r.json();
- });
- }
- function loadAllForMount(mount) {
- if (!mount) return;
- Promise.all([fetchKV(mount), fetchBranches(mount)])
- .then(([kvData, branchesStr]) => {
- renderKV(kvData, mount);
- renderBranches(branchesStr);
- })
- .catch(err => console.error('Error loading data for mount:', mount, err));
- }
- function renderKV(data, mount) {
- const div = document.getElementById('kv-list');
- div.innerHTML = '';
- const table = document.createElement('table');
- const headerRow = document.createElement('tr');
- const headerKey = document.createElement('th');
- headerKey.textContent = 'Key';
- const headerValue = document.createElement('th');
- headerValue.textContent = 'Value';
- headerRow.appendChild(headerKey);
- headerRow.appendChild(headerValue);
- table.appendChild(headerRow);
- const priorityKeys = ['fsname', 'version'];
- const orderedEntries = [];
- priorityKeys.forEach(key => {
- if (data.hasOwnProperty(key)) {
- orderedEntries.push([key, data[key]]);
- delete data[key];
- }
- });
- for (const [k, v] of Object.entries(data)) {
- orderedEntries.push([k, v]);
- }
- for (const [k, v] of orderedEntries) {
- const row = document.createElement('tr');
- const keyCell = document.createElement('td');
- keyCell.textContent = k;
- const valueCell = document.createElement('td');
- const input = document.createElement('input');
- input.type = 'text';
- input.value = v;
- input.style.width = '100%';
- input.onkeydown = function(e) {
- if (e.key === 'Enter') {
- const postUrl = '/kvs?mount=' + encodeURIComponent(mount);
- fetch(postUrl, {
- method: 'POST',
- headers: {'Content-Type': 'application/json'},
- body: JSON.stringify({[k]: input.value})
- }).then(response => {
- if (!response.ok) {
- response.text().then(body => {
- alert('Status: ' + response.status + '\nBody: ' + body);
- });
- }
- });
- }
- };
- valueCell.appendChild(input);
- row.appendChild(keyCell);
- row.appendChild(valueCell);
- table.appendChild(row);
- }
- div.appendChild(table);
- }
- function renderBranches(branchesStr) {
- const div = document.getElementById('branches-list');
- div.innerHTML = '';
- if (!branchesStr) {
- addBranchEntry();
- return;
- }
- const branches = branchesStr.split(':').map(b => b.trim()).filter(b => b);
- branches.forEach(branchStr => {
- let path = branchStr;
- let mode = 'RW';
- let minfreespace = '';
- const eqPos = branchStr.indexOf('=');
- if (eqPos !== -1) {
- path = branchStr.substring(0, eqPos).trim();
- const options = branchStr.substring(eqPos + 1).trim();
- if (options) {
- const parts = options.split(',');
- if (parts.length >= 1 && parts[0]) {
- mode = parts[0].trim().toUpperCase();
- }
- if (parts.length >= 2 && parts[1]) {
- minfreespace = parts[1].trim();
- }
- }
- }
- addBranchEntry(path, mode, minfreespace);
- });
- }
- let branchEntryCounter = 0;
- let pendingPathInput = null;
- function addBranchEntry(path = '', mode = 'RW', minfreespace = '') {
- const container = document.getElementById('branches-list');
+ function loadMounts() {
+ fetch('/mounts')
+ .then(r => {
+ if (!r.ok) throw new Error('Failed to fetch mounts');
+ return r.json();
+ })
+ .then(data => {
+ g_mounts = data;
+ populateMountSelect('mount-select-advanced', function() {
+ loadAllForMount(this.value);
+ });
+ populateMountSelect('mount-select-branches', function() {
+ loadAllForMount(this.value);
+ });
+ if (g_mounts.length > 0) {
+ loadAllForMount(g_mounts[0]);
+ }
+ })
+ .catch(err => console.error('Error loading mounts:', err));
+ }
+ function fetchBranches(mount) {
+ return fetch('/kvs/branches?mount=' + encodeURIComponent(mount))
+ .then(r => {
+ if (!r.ok) throw new Error('Failed to fetch branches');
+ return r.json();
+ });
+ }
+ function fetchKV(mount) {
+ return fetch('/kvs?mount=' + encodeURIComponent(mount))
+ .then(r => {
+ if (!r.ok) throw new Error('Failed to fetch kvs');
+ return r.json();
+ });
+ }
+ function loadAllForMount(mount) {
+ if (!mount) return;
+ Promise.all([fetchKV(mount), fetchBranches(mount)])
+ .then(([kvData, branchesStr]) => {
+ renderKV(kvData, mount);
+ renderBranches(branchesStr);
+ })
+ .catch(err => console.error('Error loading data for mount:', mount, err));
+ }
+ function renderKV(data, mount) {
+ const div = document.getElementById('kv-list');
+ div.innerHTML = '';
+ const table = document.createElement('table');
+ const headerRow = document.createElement('tr');
+ const headerKey = document.createElement('th');
+ headerKey.textContent = 'Key';
+ const headerValue = document.createElement('th');
+ headerValue.textContent = 'Value';
+ headerRow.appendChild(headerKey);
+ headerRow.appendChild(headerValue);
+ table.appendChild(headerRow);
+ const priorityKeys = ['fsname', 'version'];
+ const orderedEntries = [];
+ priorityKeys.forEach(key => {
+ if (data.hasOwnProperty(key)) {
+ orderedEntries.push([key, data[key]]);
+ delete data[key];
+ }
+ });
+ for (const [k, v] of Object.entries(data)) {
+ orderedEntries.push([k, v]);
+ }
+ for (const [k, v] of orderedEntries) {
+ const row = document.createElement('tr');
+ const keyCell = document.createElement('td');
+ keyCell.textContent = k;
+ const valueCell = document.createElement('td');
+ const input = document.createElement('input');
+ input.type = 'text';
+ input.value = v;
+ input.style.width = '100%';
+ input.onkeydown = function(e) {
+ if (e.key === 'Enter') {
+ const postUrl = '/kvs?mount=' + encodeURIComponent(mount);
+ fetch(postUrl, {
+ method: 'POST',
+ headers: {'Content-Type': 'application/json'},
+ body: JSON.stringify({[k]: input.value})
+ }).then(response => {
+ if (!response.ok) {
+ response.text().then(body => {
+ alert('Status: ' + response.status + '\nBody: ' + body);
+ });
+ }
+ });
+ }
+ };
+ valueCell.appendChild(input);
+ row.appendChild(keyCell);
+ row.appendChild(valueCell);
+ table.appendChild(row);
+ }
+ div.appendChild(table);
+ }
+ function renderBranches(branchesStr) {
+ const div = document.getElementById('branches-list');
+ div.innerHTML = '';
+ if (!branchesStr) {
+ addBranchEntry();
+ return;
+ }
+ const branches = branchesStr.split(':').map(b => b.trim()).filter(b => b);
+ branches.forEach(branchStr => {
+ let path = branchStr;
+ let mode = 'RW';
+ let minfreespace = '';
+ const eqPos = branchStr.indexOf('=');
+ if (eqPos !== -1) {
+ path = branchStr.substring(0, eqPos).trim();
+ const options = branchStr.substring(eqPos + 1).trim();
+ if (options) {
+ const parts = options.split(',');
+ if (parts.length >= 1 && parts[0]) {
+ mode = parts[0].trim().toUpperCase();
+ }
+ if (parts.length >= 2 && parts[1]) {
+ minfreespace = parts[1].trim();
+ }
+ }
+ }
+ addBranchEntry(path, mode, minfreespace);
+ });
+ }
+ let branchEntryCounter = 0;
+ let pendingPathInput = null;
+ function addBranchEntry(path = '', mode = 'RW', minfreespace = '') {
+ const container = document.getElementById('branches-list');
const entry = document.createElement('div');
entry.className = 'branch-entry';
entry.id = 'branch-entry-' + branchEntryCounter++;
@@ -391,6 +402,7 @@
pathInput.placeholder = 'Path';
pathInput.value = path;
const pathBtn = document.createElement('button');
+ pathBtn.className = 'path-btn';
pathBtn.textContent = 'Path';
pathBtn.onclick = () => openPathModal(pathInput);
const modeSelect = document.createElement('select');
@@ -403,85 +415,85 @@
modeSelect.appendChild(opt);
});
const minfreespaceInput = document.createElement('input');
- minfreespaceInput.type = 'text';
- minfreespaceInput.className = 'branch-minfreespace';
- minfreespaceInput.placeholder = 'MinFreeSpace';
- minfreespaceInput.value = minfreespace;
- const removeBtn = document.createElement('button');
- removeBtn.className = 'branch-remove';
- removeBtn.textContent = 'Remove';
- removeBtn.onclick = () => entry.remove();
- entry.appendChild(pathInput);
- entry.appendChild(pathBtn);
- entry.appendChild(modeSelect);
- entry.appendChild(minfreespaceInput);
- entry.appendChild(removeBtn);
- container.appendChild(entry);
- }
- function openPathModal(targetInput) {
- pendingPathInput = targetInput;
- const modal = document.getElementById('pathModal');
- const mountList = document.getElementById('mount-list');
- mountList.innerHTML = '';
- g_mounts.forEach(m => {
- const div = document.createElement('div');
- div.className = 'mount-list-item';
- div.textContent = m;
- div.onclick = () => {
- if (pendingPathInput) {
- pendingPathInput.value = m;
- }
- closePathModal();
- };
- mountList.appendChild(div);
- });
- modal.style.display = 'block';
- }
- function closePathModal() {
- document.getElementById('pathModal').style.display = 'none';
- pendingPathInput = null;
- }
- function submitBranches() {
- const mount = document.getElementById('mount-select-branches').value;
- const entries = document.querySelectorAll('.branch-entry');
- const branches = [];
- entries.forEach(entry => {
- const pathInput = entry.querySelector('.branch-path');
- const modeSelect = entry.querySelector('.branch-mode');
- const minfreespaceInput = entry.querySelector('.branch-minfreespace');
- if (pathInput && pathInput.value.trim()) {
- let branchStr = pathInput.value.trim();
- if (modeSelect && modeSelect.value && modeSelect.value !== 'RW') {
- branchStr += '=' + modeSelect.value;
- } else {
- branchStr += '=RW';
- }
- if (minfreespaceInput && minfreespaceInput.value.trim()) {
- branchStr += ',' + minfreespaceInput.value.trim();
- }
- branches.push(branchStr);
- }
- });
- const branchesStr = branches.join(':');
- fetch('/kvs?mount=' + encodeURIComponent(mount), {
- method: 'POST',
- headers: {'Content-Type': 'application/json'},
- body: JSON.stringify({"branches": branchesStr})
- }).then(response => {
- if (!response.ok) {
- response.text().then(body => {
- alert('Status: ' + response.status + '\nBody: ' + body);
- });
- }
- });
- }
- window.onclick = function(event) {
- const modal = document.getElementById('pathModal');
- if (event.target === modal) {
- closePathModal();
- }
- }
- window.onload = () => { loadMounts(); };
-
-