From bed1852110fe39d8ddfe6955b07e6ce25956985c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=90=D0=BD=D1=82=D0=BE=D0=BD=20=D0=A2=D1=80=D0=BE=D1=88?=
=?UTF-8?q?=D0=B8=D0=BD?=
Date: Tue, 22 Sep 2026 00:51:07 +0300
Subject: [PATCH] ui: lay the EUICCInfo2 chip fields out in two columns
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The short EUICCInfo2 fields (versions, card resources, category, PPRs, …)
were one per row in the wide right-hand box, wasting half of it.
- esimChipValueWide(): a row needs the full width when its value is a
list or a long token (>24 chars or ', '), so short scalars pair up.
- esimChipBox() gained a twoColumns mode: rows in a responsive
grid-cols-1 sm:grid-cols-2 grid with long values spanning both columns;
the other boxes keep their single-column rows.
- esimRenderChip() renders the EUICCInfo2 box with two columns.
- style.css rebuilt (sm:grid-cols-2, sm:col-span-2).
- tests: the wide/short rule, the two-column markup and the render call;
help EN/RU and AGENTS note the layout; sw.js simple-v233.
---
frontend/help-ru.html | 2 +-
frontend/help.html | 2 +-
frontend/index.html | 22 ++++++++++++++++++----
frontend/style.css | 10 ++++++++++
frontend/sw.js | 2 +-
frontend/tests/esim.test.js | 36 +++++++++++++++++++++++++++++++++++-
6 files changed, 66 insertions(+), 8 deletions(-)
diff --git a/frontend/help-ru.html b/frontend/help-ru.html
index 133eac2..5b14eeb 100644
--- a/frontend/help-ru.html
+++ b/frontend/help-ru.html
@@ -497,7 +497,7 @@
8.8 eSIM / LPA (локальные операции)
';
html += '
' + esc(title) + '
';
+ if (twoColumns) html += '
';
for (const [k, v] of rows) {
- html += '
';
+ const cls = twoColumns ? 'flex gap-2 min-w-0' : 'flex gap-2 mb-0.5';
+ html += '
';
if (k) html += '' + esc(k) + '';
html += '' + esc(v) + '
';
}
+ if (twoColumns) html += '
';
return html + '
';
}
@@ -1701,7 +1715,7 @@ function esimRenderChip() {
esimChipBox(t('Addresses'), esimChipSectionRows(c.addresses)),
esimChipBox(t('Rules authorisation table'), esimChipSectionRows(c.rat)),
].filter(Boolean);
- const right = esimChipBox('EUICCInfo2', esimChipSectionRows(c.info2));
+ const right = esimChipBox('EUICCInfo2', esimChipSectionRows(c.info2), true);
if (!left.length && !right) {
el.innerHTML = '
' + esc(t('No data')) + '';
return;
diff --git a/frontend/style.css b/frontend/style.css
index 1d31825..63be6ee 100644
--- a/frontend/style.css
+++ b/frontend/style.css
@@ -1977,6 +1977,16 @@ video {
color: rgb(203 213 225 / var(--tw-text-opacity, 1));
}
+@media (min-width: 640px) {
+ .sm\:col-span-2 {
+ grid-column: span 2 / span 2;
+ }
+
+ .sm\:grid-cols-2 {
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ }
+}
+
@media (min-width: 1024px) {
.lg\:col-span-1 {
grid-column: span 1 / span 1;
diff --git a/frontend/sw.js b/frontend/sw.js
index a434e5a..ae902e2 100644
--- a/frontend/sw.js
+++ b/frontend/sw.js
@@ -1,4 +1,4 @@
-const CACHE = 'simple-v232';
+const CACHE = 'simple-v233';
const URLS = [
'index.html',
'help.html',
diff --git a/frontend/tests/esim.test.js b/frontend/tests/esim.test.js
index c131064..fcfee77 100644
--- a/frontend/tests/esim.test.js
+++ b/frontend/tests/esim.test.js
@@ -24,7 +24,7 @@ function extractFunc(src, name) {
let code = '';
for (const fn of ['esimLabel', 'esimGroupEid', 'esimFieldRows', 'esimResultText',
'esimStateLabel', 'esimOperationsText', 'esimProfileRows', 'esimIconDataUrl',
- 'esimChipSectionRows', 'esimChipBox', 'esimSwitchStatus']) {
+ 'esimChipSectionRows', 'esimChipValueWide', 'esimChipBox', 'esimSwitchStatus']) {
code += extractFunc(html, fn) + '\n';
}
for (const c of ['ESIM_CHIP_LABELS', 'ESIM_RESULT_KEYS']) {
@@ -179,6 +179,40 @@ test('the chip boxes prefer wrapping at spaces over breaking words', () => {
assert.doesNotMatch(render, /break-all/);
});
+test('esimChipValueWide keeps short scalars in one column', () => {
+ assert.strictEqual(esimChipValueWide('Profile version', '2.3.1'), false);
+ assert.strictEqual(
+ esimChipValueWide('Card resource / Free non-volatile memory', '439084'), false);
+ assert.strictEqual(esimChipValueWide('SS accreditation number', 'ED-ZI-UP-0826'), false);
+ assert.strictEqual(
+ esimChipValueWide('RSP capability', 'additionalProfile, testProfileSupport'), true);
+ assert.strictEqual(
+ esimChipValueWide('CI PKI (verification) / Subject key identifier',
+ '81370F5125D0B1D408D4C3B232E6D25E795BEBFB'), true);
+});
+
+test('esimChipBox lays short fields out in two columns', () => {
+ const box = esimChipBox('EUICCInfo2', [
+ ['Profile version', '2.3.1'], ['SVN', '2.2.2'],
+ ['UICC capability', 'usimSupport, isimSupport'],
+ ], true);
+ assert.match(box, /sm:grid-cols-2/);
+ const cells = box.match(/
{
+ const fn = extractFunc(html, 'esimRenderChip');
+ assert.match(fn, /esimChipBox\('EUICCInfo2', esimChipSectionRows\(c\.info2\), true\)/);
+});
+
test('the chip view groups the sections into a grid', () => {
const fn = extractFunc(html, 'esimRenderChip');
assert.match(fn, /lg:grid-cols-3/);