diff --git a/index.html b/index.html index 12adb00b..88391caa 100644 --- a/index.html +++ b/index.html @@ -141,15 +141,96 @@ outline: none; border-color: #666; } - .branch-path { - flex: 1; - min-width: 200px; - } - .branch-mode { - width: 80px; - } - .branch-minfreespace { - width: 100px; + .branch-minfreespace-value { + flex: 0 0 55px; + border-radius: 4px 0 0 4px; + min-width: 55px; + background-color: #333; + color: #e0e0e0; + border: 1px solid #555; + border-right: none; + } + .branch-minfreespace-value:focus { + border-color: #666; + border-right: none; + } + .branch-minfreespace-unit { + flex: 0 0 55px; + border: 1px solid #555; + border-left: none; + border-radius: 0 4px 4px 0; + padding-right: 5px; + background-color: #333; + color: #e0e0e0; + text-align: center; + } + .branch-minfreespace-unit:focus { + outline: none; + border: 1px solid #666; + border-left: none; + } + .branch-path { + flex: 1; + min-width: 200px; + width: 100%; + } + .branch-mode { + width: 80px; + flex-shrink: 0; + } + .branch-controls-wrapper { + display: flex; + align-items: center; + gap: 8px; + margin-left: auto; + flex-shrink: 0; + flex-wrap: wrap; + } + .branch-minfreespace-container { + display: flex; + gap: 0; + align-items: stretch; + border: none; + border-radius: 4px; + background-color: transparent; + padding: 0; + flex-shrink: 0; + } + .branches-header { + display: flex; + align-items: center; + gap: 10px; + padding: 6px 8px; + margin-bottom: 10px; + background-color: #252525; + border: 1px solid #444; + border-radius: 4px; + font-weight: bold; + font-size: 13px; + color: #e0e0e0; + } + .header-path { + flex: 1; + min-width: 200px; + } + .header-path-btn { + width: 70px; + } + .header-mode { + width: 80px; + text-align: center; + } + .header-minfreespace { + width: 120px; + text-align: left; + } + .header-actions { + display: flex; + gap: 8px; + } + .header-actions div { + width: 28px; + text-align: center; } .branch-remove { background-color: #8b0000; @@ -184,50 +265,158 @@ .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 { + background-color: #1565c0; + color: white; + border: none; + padding: 5px 10px; + cursor: pointer; + margin-right: 0; + flex-shrink: 0; + } .path-btn:hover { background-color: #1976d2; } - .branch-move-btn { - background-color: #424242; - color: white; - border: none; - cursor: pointer; - margin-right: 3px; - width: 28px; - height: 28px; - display: flex; - align-items: center; - justify-content: center; - font-size: 16px; - font-weight: bold; - } + .branch-move-btn { + background-color: #424242; + color: white; + border: none; + cursor: pointer; + width: 28px; + height: 28px; + display: flex; + align-items: center; + justify-content: center; + font-size: 16px; + font-weight: bold; + flex-shrink: 0; + } .branch-move-btn:hover { background-color: #616161; } .branch-move-btn:disabled { cursor: not-allowed; } - .branch-entry { - display: flex; - align-items: center; - padding: 8px; - margin: 5px 0; - background-color: #2d2d2d; - border-radius: 4px; - cursor: grab; - transition: background-color 0.2s, box-shadow 0.2s; - flex-wrap: wrap; - gap: 8px; - min-height: 60px; - } + .branch-entry { + display: flex; + align-items: center; + padding: 8px; + margin: 5px 0; + background-color: #2d2d2d; + border-radius: 4px; + cursor: grab; + transition: background-color 0.2s, box-shadow 0.2s; + gap: 8px; + min-height: 60px; + } + .branch-entry:hover { + background-color: #3d3d3d; + box-shadow: 0 2px 8px rgba(0,0,0,0.3); + } + .branch-entry.dragging { + cursor: grabbing; + box-shadow: 0 4px 12px rgba(0,0,0,0.5); + } + .branch-entry.drag-over { + border: 2px solid #1565c0; + } + .branch-path { + flex: 1; + min-width: 200px; + } + .branch-mode { + width: 80px; + flex-shrink: 0; + } + .branch-controls-wrapper { + display: flex; + align-items: center; + gap: 8px; + flex-shrink: 0; + } + .branch-minfreespace-container { + display: flex; + gap: 0; + align-items: stretch; + border: none; + border-radius: 4px; + background-color: transparent; + padding: 0; + flex-shrink: 0; + } + .branch-minfreespace-value { + width: 60px; + border-radius: 4px 0 0 4px; + min-width: 60px; + background-color: #333; + color: #e0e0e0; + border: 1px solid #555; + border-right: none; + } + .branch-minfreespace-value:focus { + border-color: #666; + border-right: none; + } + .branch-minfreespace-unit { + width: 60px; + border: 1px solid #555; + border-left: none; + border-radius: 0 4px 4px 0; + padding-right: 5px; + background-color: #333; + color: #e0e0e0; + text-align: center; + min-width: 60px; + } + .branch-minfreespace-unit:focus { + outline: none; + border: 1px solid #666; + border-left: none; + } + .path-btn { + width: 70px; + background-color: #1565c0; + color: white; + border: none; + padding: 5px 10px; + cursor: pointer; + flex-shrink: 0; + } + .path-btn:hover { + background-color: #1976d2; + } + .branch-move-btn { + background-color: #424242; + color: white; + border: none; + cursor: pointer; + width: 28px; + height: 28px; + display: flex; + align-items: center; + justify-content: center; + font-size: 16px; + font-weight: bold; + flex-shrink: 0; + } + .branch-move-btn:hover { + background-color: #616161; + } + .branch-move-btn:disabled { + cursor: not-allowed; + } + .branch-remove { + width: 80px; + background-color: #8b0000; + color: white; + border: none; + padding: 5px 10px; + cursor: pointer; + flex-shrink: 0; + } + .branch-remove:hover { + background-color: #a00000; + } .branch-entry:hover { background-color: #3d3d3d; box-shadow: 0 2px 8px rgba(0,0,0,0.3); @@ -325,7 +514,7 @@ min-width: auto; } } - @media (max-width: 768px) { + @media (max-width: 768px) { .controls-row { flex-direction: column; align-items: stretch; @@ -347,18 +536,62 @@ .branch-entry { flex-direction: column; align-items: stretch; - gap: 10px; + gap: 8px; } - .branch-path, - .branch-mode, - .branch-minfreespace { + .branch-path { width: 100%; min-width: auto; - margin-bottom: 5px; } - .path-btn { + .branch-controls-wrapper { + flex-direction: row; + gap: 8px; width: 100%; - margin: 0; + flex-wrap: wrap; + } + .path-btn, + .branch-mode, + .branch-remove { + flex: 1; + min-width: 60px; + } + .branch-minfreespace-container { + display: flex; + gap: 0; + margin-bottom: 0; + border: none; + border-radius: 4px; + background-color: transparent; + padding: 0; + flex: 1; + min-width: 120px; + } + .branch-minfreespace-value { + width: 60px; + min-width: 60px; + border-radius: 4px 0 0 4px; + background-color: #333; + color: #e0e0e0; + border: 1px solid #555; + border-right: none; + } + .branch-minfreespace-value:focus { + border-color: #666; + border-right: none; + } + .branch-minfreespace-unit { + width: 60px; + min-width: 60px; + border: 1px solid #555; + border-left: none; + border-radius: 0 4px 4px 0; + background-color: #333; + color: #e0e0e0; + text-align: center; + } + .branch-minfreespace-unit:focus { + outline: none; + border: 1px solid #666; + border-left: none; } .branch-move-btn { flex: 1; @@ -366,7 +599,6 @@ height: 44px; } .branch-remove { - flex: 2; padding: 12px; min-height: 44px; } @@ -391,7 +623,7 @@ font-size: 14px; max-width: 90%; } - } + } @media (max-width: 480px) { .tab { flex-direction: column; @@ -609,6 +841,9 @@ function renderBranches(branchesStr) { const div = document.getElementById('branches-list'); div.innerHTML = ''; + + + if (!branchesStr) { addBranchEntry(); return; @@ -648,50 +883,87 @@ entry.addEventListener('dragover', handleDragOver); entry.addEventListener('dragleave', handleDragLeave); entry.addEventListener('drop', handleDrop); - const pathInput = document.createElement('input'); - pathInput.type = 'text'; - pathInput.className = 'branch-path'; - 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'); - modeSelect.className = 'branch-mode'; - ['RW', 'NC', 'RO'].forEach(m => { + const pathInput = document.createElement('input'); + pathInput.type = 'text'; + pathInput.className = 'branch-path'; + pathInput.placeholder = 'path'; + pathInput.value = path; + const controlsWrapper = document.createElement('div'); + controlsWrapper.className = 'branch-controls-wrapper'; + const pathBtn = document.createElement('button'); + pathBtn.className = 'path-btn'; + pathBtn.textContent = 'Path'; + pathBtn.onclick = () => openPathModal(pathInput); + const modeSelect = document.createElement('select'); + modeSelect.className = 'branch-mode'; + ['RW', 'NC', 'RO'].forEach(m => { + const opt = document.createElement('option'); + opt.value = m; + opt.textContent = m; + if (m === mode) opt.selected = true; + modeSelect.appendChild(opt); + }); + const minfreespaceContainer = document.createElement('div'); + minfreespaceContainer.className = 'branch-minfreespace-container'; + const minfreespaceValueInput = document.createElement('input'); + minfreespaceValueInput.type = 'number'; + minfreespaceValueInput.className = 'branch-minfreespace-value'; + minfreespaceValueInput.placeholder = 'minfreespace'; + minfreespaceValueInput.min = '0'; + const minfreespaceUnitSelect = document.createElement('select'); + minfreespaceUnitSelect.className = 'branch-minfreespace-unit'; + const units = [ + {value: 'B', label: 'B'}, + {value: 'K', label: 'KiB'}, + {value: 'M', label: 'MiB'}, + {value: 'G', label: 'GiB'}, + {value: 'T', label: 'TiB'} + ]; + units.forEach(u => { const opt = document.createElement('option'); - opt.value = m; - opt.textContent = m; - if (m === mode) opt.selected = true; - modeSelect.appendChild(opt); + opt.value = u.value; + opt.textContent = u.label; + minfreespaceUnitSelect.appendChild(opt); }); - const minfreespaceInput = document.createElement('input'); - minfreespaceInput.type = 'text'; - minfreespaceInput.className = 'branch-minfreespace'; - minfreespaceInput.placeholder = 'minfreespace'; - minfreespaceInput.value = minfreespace; - const moveUpBtn = document.createElement('button'); - moveUpBtn.className = 'branch-move-btn branch-move-up'; - moveUpBtn.innerHTML = '▲'; - moveUpBtn.title = 'Move up'; - moveUpBtn.onclick = () => moveEntryUp(entry); - const moveDownBtn = document.createElement('button'); - moveDownBtn.className = 'branch-move-btn branch-move-down'; - moveDownBtn.innerHTML = '▼'; - moveDownBtn.title = 'Move down'; - moveDownBtn.onclick = () => moveEntryDown(entry); - 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(moveUpBtn); - entry.appendChild(moveDownBtn); - entry.appendChild(removeBtn); + let minfreespaceValue = ''; + let minfreespaceUnit = 'G'; + if (minfreespace) { + const match = minfreespace.match(/^(\d+)([BKMG])?$/i); + if (match) { + minfreespaceValue = match[1]; + if (match[2]) { + minfreespaceUnit = match[2].toUpperCase(); + } + } else { + minfreespaceValue = minfreespace; + } + } + minfreespaceValueInput.value = minfreespaceValue; + minfreespaceUnitSelect.value = minfreespaceUnit; + minfreespaceContainer.appendChild(minfreespaceValueInput); + minfreespaceContainer.appendChild(minfreespaceUnitSelect); + const moveUpBtn = document.createElement('button'); + moveUpBtn.className = 'branch-move-btn branch-move-up'; + moveUpBtn.innerHTML = '▲'; + moveUpBtn.title = 'Move up'; + moveUpBtn.onclick = () => moveEntryUp(entry); + const moveDownBtn = document.createElement('button'); + moveDownBtn.className = 'branch-move-btn branch-move-down'; + moveDownBtn.innerHTML = '▼'; + moveDownBtn.title = 'Move down'; + moveDownBtn.onclick = () => moveEntryDown(entry); + const removeBtn = document.createElement('button'); + removeBtn.className = 'branch-remove'; + removeBtn.textContent = 'Remove'; + removeBtn.onclick = () => entry.remove(); + controlsWrapper.appendChild(pathBtn); + controlsWrapper.appendChild(modeSelect); + controlsWrapper.appendChild(minfreespaceContainer); + controlsWrapper.appendChild(moveUpBtn); + controlsWrapper.appendChild(moveDownBtn); + controlsWrapper.appendChild(removeBtn); + entry.appendChild(pathInput); + entry.appendChild(controlsWrapper); container.appendChild(entry); } let draggedEntry = null; @@ -783,7 +1055,8 @@ entries.forEach(entry => { const pathInput = entry.querySelector('.branch-path'); const modeSelect = entry.querySelector('.branch-mode'); - const minfreespaceInput = entry.querySelector('.branch-minfreespace'); + const minfreespaceValueInput = entry.querySelector('.branch-minfreespace-value'); + const minfreespaceUnitSelect = entry.querySelector('.branch-minfreespace-unit'); if (pathInput && pathInput.value.trim()) { let branchStr = pathInput.value.trim(); if (modeSelect && modeSelect.value && modeSelect.value !== 'RW') { @@ -791,8 +1064,10 @@ } else { branchStr += '=RW'; } - if (minfreespaceInput && minfreespaceInput.value.trim()) { - branchStr += ',' + minfreespaceInput.value.trim(); + if (minfreespaceValueInput && minfreespaceValueInput.value.trim() && minfreespaceUnitSelect) { + const value = minfreespaceValueInput.value.trim(); + const unit = minfreespaceUnitSelect.value; + branchStr += ',' + value + unit; } branches.push(branchStr); }