v3.11.0 editor polish: fixed TAR table layout, ADM placeholder
The TAR table used the default auto layout with w-full, so the browser distributed the surplus width across all columns and TAR/MSL/description looked evenly spread. table-fixed with explicit column widths (TAR w-28, MSL w-20, action w-12; the description column takes the remainder) and w-full inputs keep the first two columns tight and left-packed. The ADM placeholder is just "ADM" now. sw cache simple-v365. Tests: 665 Python + 787 frontend green; the whole inline PWA script syntax-checked.
This commit is contained in:
+7
-7
@@ -1659,19 +1659,19 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<label for="cards-adm" class="w-10 shrink-0 text-xs text-gray-600 dark:text-slate-400">ADM</label>
|
<label for="cards-adm" class="w-10 shrink-0 text-xs text-gray-600 dark:text-slate-400">ADM</label>
|
||||||
<input id="cards-adm" class="flex-1 min-w-0 border border-gray-300 dark:border-slate-600 text-sm rounded px-2 py-1.5 dark:bg-slate-800 font-mono text-center" maxlength="16" placeholder="ADM (optional)">
|
<input id="cards-adm" class="flex-1 min-w-0 border border-gray-300 dark:border-slate-600 text-sm rounded px-2 py-1.5 dark:bg-slate-800 font-mono text-center" maxlength="16" placeholder="ADM">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p class="text-xs text-gray-500 dark:text-slate-400 mt-2" data-l10n="All codes are optional">All codes are optional</p>
|
<p class="text-xs text-gray-500 dark:text-slate-400 mt-2" data-l10n="All codes are optional">All codes are optional</p>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<fieldset class="border border-gray-200 dark:border-slate-700 rounded p-3 flex-1 min-w-0">
|
<fieldset class="border border-gray-200 dark:border-slate-700 rounded p-3 flex-1 min-w-0">
|
||||||
<legend class="px-1 text-xs font-medium text-gray-500 dark:text-slate-400" data-l10n="TAR">TAR</legend>
|
<legend class="px-1 text-xs font-medium text-gray-500 dark:text-slate-400" data-l10n="TAR">TAR</legend>
|
||||||
<table class="w-full text-sm mb-2">
|
<table class="w-full table-fixed text-sm mb-2">
|
||||||
<thead><tr>
|
<thead><tr>
|
||||||
<th class="text-left py-1 px-2 border-b border-gray-200 dark:border-slate-700" data-l10n="TAR">TAR</th>
|
<th class="w-28 text-left py-1 px-2 border-b border-gray-200 dark:border-slate-700" data-l10n="TAR">TAR</th>
|
||||||
<th class="text-left py-1 px-2 border-b border-gray-200 dark:border-slate-700" data-l10n="MSL">MSL</th>
|
<th class="w-20 text-left py-1 px-2 border-b border-gray-200 dark:border-slate-700" data-l10n="MSL">MSL</th>
|
||||||
<th class="text-left py-1 px-2 border-b border-gray-200 dark:border-slate-700" data-l10n="Description">Description</th>
|
<th class="text-left py-1 px-2 border-b border-gray-200 dark:border-slate-700" data-l10n="Description">Description</th>
|
||||||
<th class="w-8 border-b border-gray-200 dark:border-slate-700"></th>
|
<th class="w-12 border-b border-gray-200 dark:border-slate-700"></th>
|
||||||
</tr></thead>
|
</tr></thead>
|
||||||
<tbody id="cards-tars"></tbody>
|
<tbody id="cards-tars"></tbody>
|
||||||
</table>
|
</table>
|
||||||
@@ -11897,8 +11897,8 @@ const CARDS_TAR_ROLE_DESC = {
|
|||||||
function cardsTarRowHtml(e, i) {
|
function cardsTarRowHtml(e, i) {
|
||||||
const cls = 'border border-gray-300 dark:border-slate-600 text-sm rounded px-2 py-1.5 dark:bg-slate-800 font-mono';
|
const cls = 'border border-gray-300 dark:border-slate-600 text-sm rounded px-2 py-1.5 dark:bg-slate-800 font-mono';
|
||||||
const role = CARDS_TAR_ROLES[i] || '';
|
const role = CARDS_TAR_ROLES[i] || '';
|
||||||
let cells = '<td class="py-1 px-2"><input id="cards-tr-' + i + '-tar" class="w-24 ' + cls + '" maxlength="6" placeholder="TAR" value="' + esc(e.tar || '') + '"></td>' +
|
let cells = '<td class="py-1 px-2"><input id="cards-tr-' + i + '-tar" class="w-full ' + cls + '" maxlength="6" placeholder="TAR" value="' + esc(e.tar || '') + '"></td>' +
|
||||||
'<td class="py-1 px-2"><input id="cards-tr-' + i + '-msl" class="w-14 ' + cls + '" maxlength="2" placeholder="MSL" value="' + esc(e.msl || '') + '" title="' + esc(t('MSL (Minimum SPI1, one hex byte)')) + '"></td>';
|
'<td class="py-1 px-2"><input id="cards-tr-' + i + '-msl" class="w-full ' + cls + '" maxlength="2" placeholder="MSL" value="' + esc(e.msl || '') + '" title="' + esc(t('MSL (Minimum SPI1, one hex byte)')) + '"></td>';
|
||||||
if (role) {
|
if (role) {
|
||||||
cells += '<td class="py-1 px-2 text-xs text-gray-600 dark:text-slate-400">' + esc(CARDS_TAR_ROLE_DESC[role] || '') + '</td>' +
|
cells += '<td class="py-1 px-2 text-xs text-gray-600 dark:text-slate-400">' + esc(CARDS_TAR_ROLE_DESC[role] || '') + '</td>' +
|
||||||
'<td class="py-1 px-2"></td>';
|
'<td class="py-1 px-2"></td>';
|
||||||
|
|||||||
@@ -1024,6 +1024,10 @@ video {
|
|||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.table-fixed {
|
||||||
|
table-layout: fixed;
|
||||||
|
}
|
||||||
|
|
||||||
.border-collapse {
|
.border-collapse {
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
const CACHE = 'simple-v364';
|
const CACHE = 'simple-v365';
|
||||||
const URLS = [
|
const URLS = [
|
||||||
'index.html',
|
'index.html',
|
||||||
'help.html',
|
'help.html',
|
||||||
|
|||||||
@@ -535,8 +535,8 @@ test('packing without a selected preset uses the spec default TAR', () => {
|
|||||||
test('the TAR row values are left-aligned like the headers', () => {
|
test('the TAR row values are left-aligned like the headers', () => {
|
||||||
const out = cardsTarRowHtml({ tar: 'AF4D01', msl: '0A', desc: 'x' }, 3);
|
const out = cardsTarRowHtml({ tar: 'AF4D01', msl: '0A', desc: 'x' }, 3);
|
||||||
assert.doesNotMatch(out, /text-center/);
|
assert.doesNotMatch(out, /text-center/);
|
||||||
assert.match(out, /<td class="py-1 px-2"><input id="cards-tr-3-tar"/);
|
assert.match(out, /<td class="py-1 px-2"><input id="cards-tr-3-tar" class="w-full/);
|
||||||
assert.match(out, /<td class="py-1 px-2"><input id="cards-tr-3-msl"/);
|
assert.match(out, /<td class="py-1 px-2"><input id="cards-tr-3-msl" class="w-full/);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('the TAR table renders the role rows and adds/removes free rows', () => {
|
test('the TAR table renders the role rows and adds/removes free rows', () => {
|
||||||
|
|||||||
@@ -186,6 +186,12 @@ test('the PIN/ADM and TAR fieldsets share one responsive row', () => {
|
|||||||
// the codes are one-line rows: label left, input right
|
// the codes are one-line rows: label left, input right
|
||||||
assert.match(row, /class="flex items-center gap-2"[\s\S]*?for="cards-pin1"[\s\S]*?id="cards-pin1"/);
|
assert.match(row, /class="flex items-center gap-2"[\s\S]*?for="cards-pin1"[\s\S]*?id="cards-pin1"/);
|
||||||
assert.match(row, /for="cards-pin1"[^>]*class="w-10 shrink-0/);
|
assert.match(row, /for="cards-pin1"[^>]*class="w-10 shrink-0/);
|
||||||
|
// the TAR table is fixed-layout so the columns hug their content and the
|
||||||
|
// description absorbs the rest (no even spreading)
|
||||||
|
assert.match(row, /<table class="w-full table-fixed text-sm mb-2">/);
|
||||||
|
assert.match(row, /<th class="w-28 text-left[^"]*" data-l10n="TAR"/);
|
||||||
|
assert.match(row, /<th class="w-20 text-left[^"]*" data-l10n="MSL"/);
|
||||||
|
assert.match(row, /<th class="w-12[^"]*"><\/th>/);
|
||||||
// the hint is the short form
|
// the hint is the short form
|
||||||
assert.match(row, /data-l10n="All codes are optional"/);
|
assert.match(row, /data-l10n="All codes are optional"/);
|
||||||
assert.ok(!row.includes('not consumed yet'), 'the long codes hint is gone');
|
assert.ok(!row.includes('not consumed yet'), 'the long codes hint is gone');
|
||||||
@@ -230,7 +236,7 @@ test('the ADM field sits in the PIN/ADM fieldset of the editor', () => {
|
|||||||
const fieldsets = [...html.matchAll(/<fieldset[\s\S]*?<\/fieldset>/g)].map(m => m[0]);
|
const fieldsets = [...html.matchAll(/<fieldset[\s\S]*?<\/fieldset>/g)].map(m => m[0]);
|
||||||
const pinAdm = fieldsets.find(f => /data-l10n="PIN\/ADM"/.test(f));
|
const pinAdm = fieldsets.find(f => /data-l10n="PIN\/ADM"/.test(f));
|
||||||
assert.ok(pinAdm, 'PIN/ADM fieldset not found');
|
assert.ok(pinAdm, 'PIN/ADM fieldset not found');
|
||||||
assert.match(pinAdm, /id="cards-adm"[^>]*placeholder="ADM \(optional\)"/);
|
assert.match(pinAdm, /id="cards-adm"[^>]*placeholder="ADM"/);
|
||||||
// the From card button sits in the editor header, above the code fields
|
// the From card button sits in the editor header, above the code fields
|
||||||
assert.ok(html.indexOf('id="cards-iccid-from-card"') < html.indexOf('id="cards-pin1"'),
|
assert.ok(html.indexOf('id="cards-iccid-from-card"') < html.indexOf('id="cards-pin1"'),
|
||||||
'the From card button must precede the code fields');
|
'the From card button must precede the code fields');
|
||||||
|
|||||||
Reference in New Issue
Block a user