mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-03 05:59:43 +02:00
fix(mobile): give the Add Case modal a reachable submit button
mobile.css hides #createCaseModal's .set-foot below 860px, and that modal's header — unlike Settings' — carries no set-head-save. So on a phone the Create/Link button existed nowhere and the modal could not be submitted at all. Adds the header button and drives both together through switchCaseModalTab() and submitCaseModal(), so whichever one is pressed the other shows the same pending state and is equally unclickable. Following the Settings pattern also means Add Case picks up the existing .set-head-actions:has(.set-head-save) tray and .set-head-save sizing with no new CSS; the mobile.css comment that still listed Add Case as a lone-× sheet is corrected to match.
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
---
|
||||
"aicodeman": patch
|
||||
---
|
||||
|
||||
fix(mobile): give the Add Case modal a reachable submit button
|
||||
|
||||
`mobile.css` hides `#createCaseModal`'s `.set-foot` on phones, and unlike the Settings
|
||||
modal that header carries no `set-head-save` — so the Create/Link button existed nowhere
|
||||
on a phone and the modal could not be submitted at all. Adds the header button and drives
|
||||
both together, so whichever one is pressed the other shows the same pending state and is
|
||||
equally unclickable.
|
||||
|
||||
Add Case follows the Settings modal's header-save pattern, so it picks up the existing
|
||||
`.set-head-actions:has(.set-head-save)` tray and `.set-head-save` sizing below 860px with no
|
||||
new CSS; the `mobile.css` comment that still listed Add Case as a lone-× sheet is updated to
|
||||
match.
|
||||
@@ -2582,8 +2582,15 @@
|
||||
<div class="modal-content modal-lg set-shell">
|
||||
<div class="modal-header set-shell-head">
|
||||
<h3>Add Case</h3>
|
||||
<!-- mobile.css hides this modal's .set-foot, so on a phone the footer's
|
||||
Create/Link button is unreachable and the modal cannot be submitted
|
||||
at all. Mirrors the Settings modal's header Save: close first in the
|
||||
DOM so the focus trap still lands on it, row-reverse puts this to
|
||||
its left. Both buttons are driven together by switchCaseModalTab()
|
||||
and submitCaseModal(). -->
|
||||
<div class="set-head-actions">
|
||||
<button class="modal-close" onclick="app.closeCreateCaseModal()" aria-label="Close create case">×</button>
|
||||
<button class="set-head-save" id="caseModalSubmitMobile" onclick="app.submitCaseModal()">Create</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="set-body">
|
||||
|
||||
@@ -3333,8 +3333,10 @@ html:is([data-skin="paper-gray"], [data-skin="solarized-light"], [data-skin="cat
|
||||
recessed tray and matching pill geometry instead of reading as a fat
|
||||
accent pill parked beside a stray × glyph. Tray colors come from skin
|
||||
tokens, never a hardcoded black alpha, or the light skins get a grey slab.
|
||||
`:has()` keeps the tray off the two sheets that carry a lone × (Session
|
||||
Options and Add Case save from inside their own forms). */
|
||||
`:has()` keeps the tray off Session Options, the one sheet left carrying a
|
||||
lone × because it saves from inside its own per-section forms. Add Case
|
||||
now has a header save of its own (its footer is hidden below 860px, so
|
||||
that button is the only way to submit it there), and picks up the tray. */
|
||||
:is(#appSettingsModal, #sessionOptionsModal, #createCaseModal) .set-head-actions:has(.set-head-save) {
|
||||
padding: 3px;
|
||||
border: 1px solid var(--border);
|
||||
|
||||
@@ -2416,15 +2416,19 @@ Object.assign(CodemanApp.prototype, {
|
||||
// A switched-to panel starts at its own top.
|
||||
const doc = document.getElementById('createCaseDoc');
|
||||
if (doc) doc.scrollTop = 0;
|
||||
// Update submit button (hide for manage tab)
|
||||
const submitBtn = document.getElementById('caseModalSubmit');
|
||||
// Update submit buttons (hide for manage tab). Two of them: mobile.css hides
|
||||
// this modal's .set-foot, so phones submit through the header button instead.
|
||||
const submitBtns = ['caseModalSubmit', 'caseModalSubmitMobile']
|
||||
.map((id) => document.getElementById(id))
|
||||
.filter(Boolean);
|
||||
if (tabName === 'case-manage') {
|
||||
submitBtn.style.display = 'none';
|
||||
submitBtns.forEach((btn) => {
|
||||
btn.style.display = 'none';
|
||||
});
|
||||
this.renderCaseManageList();
|
||||
this.refreshDockerExports();
|
||||
} else {
|
||||
submitBtn.style.display = '';
|
||||
submitBtn.textContent =
|
||||
const label =
|
||||
tabName === 'case-create'
|
||||
? 'Create'
|
||||
: tabName === 'case-clone'
|
||||
@@ -2434,6 +2438,10 @@ Object.assign(CodemanApp.prototype, {
|
||||
: tabName === 'case-docker'
|
||||
? 'Link Docker'
|
||||
: 'Link';
|
||||
submitBtns.forEach((btn) => {
|
||||
btn.style.display = '';
|
||||
btn.textContent = label;
|
||||
});
|
||||
}
|
||||
// Focus appropriate input
|
||||
if (tabName === 'case-create') {
|
||||
@@ -2454,14 +2462,19 @@ Object.assign(CodemanApp.prototype, {
|
||||
},
|
||||
|
||||
async submitCaseModal() {
|
||||
const btn = document.getElementById('caseModalSubmit');
|
||||
const originalText = btn.textContent;
|
||||
btn.classList.add('loading');
|
||||
btn.textContent =
|
||||
// Both submit buttons move together: whichever one the user pressed, the
|
||||
// other must show the same pending state and be equally unclickable.
|
||||
const btns = ['caseModalSubmit', 'caseModalSubmitMobile'].map((id) => document.getElementById(id)).filter(Boolean);
|
||||
const originalText = btns.map((btn) => btn.textContent);
|
||||
const pendingText =
|
||||
this.caseModalTab === 'case-create' ? 'Creating...' : this.caseModalTab === 'case-clone' ? 'Cloning...' : 'Linking...';
|
||||
// A clone holds this request open for minutes; without disabling the button a
|
||||
// second click fires a second clone (the loser then fails on ALREADY_EXISTS).
|
||||
btn.disabled = true;
|
||||
btns.forEach((btn) => {
|
||||
btn.classList.add('loading');
|
||||
btn.textContent = pendingText;
|
||||
btn.disabled = true;
|
||||
});
|
||||
try {
|
||||
if (this.caseModalTab === 'case-create') {
|
||||
await this.createCase();
|
||||
@@ -2475,9 +2488,11 @@ Object.assign(CodemanApp.prototype, {
|
||||
await this.linkCase();
|
||||
}
|
||||
} finally {
|
||||
btn.classList.remove('loading');
|
||||
btn.disabled = false;
|
||||
btn.textContent = originalText;
|
||||
btns.forEach((btn, index) => {
|
||||
btn.classList.remove('loading');
|
||||
btn.disabled = false;
|
||||
btn.textContent = originalText[index];
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user