fix: keep plugin localization live and complete
This commit is contained in:
parent
3dd0ec9f1f
commit
1bc5ecfd16
|
|
@ -1059,7 +1059,7 @@
|
||||||
|
|
||||||
function loadPairing() {
|
function loadPairing() {
|
||||||
setBusy(true);
|
setBusy(true);
|
||||||
setStatus('Loading...', false);
|
setStatus(tr('ui.loading', null, 'Loading...'), false);
|
||||||
return Promise.resolve().then(function () {
|
return Promise.resolve().then(function () {
|
||||||
return pairingAPI().pairing();
|
return pairingAPI().pairing();
|
||||||
}).then(function (pairing) {
|
}).then(function (pairing) {
|
||||||
|
|
@ -1075,11 +1075,11 @@
|
||||||
function copyValue(value, label) {
|
function copyValue(value, label) {
|
||||||
if (!value) return;
|
if (!value) return;
|
||||||
if (typeof navigator === 'undefined' || !navigator.clipboard || typeof navigator.clipboard.writeText !== 'function') {
|
if (typeof navigator === 'undefined' || !navigator.clipboard || typeof navigator.clipboard.writeText !== 'function') {
|
||||||
setStatus('Clipboard unavailable', true);
|
setStatus(tr('ui.clipboardUnavailable', null, 'Clipboard unavailable'), true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
navigator.clipboard.writeText(value).then(function () {
|
navigator.clipboard.writeText(value).then(function () {
|
||||||
setStatus(label + ' copied', false);
|
setStatus(tr('ui.copied', { label: label }, '{label} copied'), false);
|
||||||
}).catch(function (err) {
|
}).catch(function (err) {
|
||||||
setStatus(text(err && err.message ? err.message : err), true);
|
setStatus(text(err && err.message ? err.message : err), true);
|
||||||
});
|
});
|
||||||
|
|
@ -1092,14 +1092,14 @@
|
||||||
copyValue(receiverTokenInput.value, 'Token');
|
copyValue(receiverTokenInput.value, 'Token');
|
||||||
});
|
});
|
||||||
rotateTokenButton.addEventListener('click', function () {
|
rotateTokenButton.addEventListener('click', function () {
|
||||||
if (typeof window.confirm === 'function' && !window.confirm('Rotate pairing token?')) return;
|
if (typeof window.confirm === 'function' && !window.confirm(tr('ui.rotateConfirm', null, 'Rotate pairing token?'))) return;
|
||||||
setBusy(true);
|
setBusy(true);
|
||||||
setStatus('Rotating...', false);
|
setStatus(tr('ui.rotating', null, 'Rotating...'), false);
|
||||||
Promise.resolve().then(function () {
|
Promise.resolve().then(function () {
|
||||||
return pairingAPI().rotateToken();
|
return pairingAPI().rotateToken();
|
||||||
}).then(function (pairing) {
|
}).then(function (pairing) {
|
||||||
applyPairing(pairing);
|
applyPairing(pairing);
|
||||||
setStatus('Token rotated', false);
|
setStatus(tr('ui.tokenRotated', null, 'Token rotated'), false);
|
||||||
}).catch(function (err) {
|
}).catch(function (err) {
|
||||||
setStatus(text(err && err.message ? err.message : err), true);
|
setStatus(text(err && err.message ? err.message : err), true);
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
|
|
|
||||||
|
|
@ -29,5 +29,11 @@
|
||||||
"ui.copyToken": "Copy Token",
|
"ui.copyToken": "Copy Token",
|
||||||
"ui.rotateToken": "Rotate Token",
|
"ui.rotateToken": "Rotate Token",
|
||||||
"ui.receiverUrl": "Receiver URL",
|
"ui.receiverUrl": "Receiver URL",
|
||||||
"ui.pairingToken": "Pairing Token"
|
"ui.pairingToken": "Pairing Token",
|
||||||
|
"ui.loading": "Loading...",
|
||||||
|
"ui.clipboardUnavailable": "Clipboard unavailable",
|
||||||
|
"ui.copied": "{label} copied",
|
||||||
|
"ui.rotateConfirm": "Rotate pairing token?",
|
||||||
|
"ui.rotating": "Rotating...",
|
||||||
|
"ui.tokenRotated": "Token rotated"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,5 +29,11 @@
|
||||||
"ui.copyToken": "Копировать токен",
|
"ui.copyToken": "Копировать токен",
|
||||||
"ui.rotateToken": "Сменить токен",
|
"ui.rotateToken": "Сменить токен",
|
||||||
"ui.receiverUrl": "URL приёмника",
|
"ui.receiverUrl": "URL приёмника",
|
||||||
"ui.pairingToken": "Токен сопряжения"
|
"ui.pairingToken": "Токен сопряжения",
|
||||||
|
"ui.loading": "Загрузка...",
|
||||||
|
"ui.clipboardUnavailable": "Буфер обмена недоступен",
|
||||||
|
"ui.copied": "{label} скопирован",
|
||||||
|
"ui.rotateConfirm": "Сменить токен сопряжения?",
|
||||||
|
"ui.rotating": "Смена токена...",
|
||||||
|
"ui.tokenRotated": "Токен изменён"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -505,7 +505,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function render() {
|
function render() {
|
||||||
countEl.textContent = entries.length + ' entr' + (entries.length === 1 ? 'y' : 'ies');
|
countEl.textContent = tr(
|
||||||
|
entries.length === 1 ? 'ui.entryCount.one' : 'ui.entryCount.many',
|
||||||
|
{ count: entries.length },
|
||||||
|
entries.length === 1 ? '{count} entry' : '{count} entries'
|
||||||
|
);
|
||||||
statusEl.textContent = statusText;
|
statusEl.textContent = statusText;
|
||||||
statusEl.className = 'journal-status' + (statusClass ? ' ' + statusClass : '');
|
statusEl.className = 'journal-status' + (statusClass ? ' ' + statusClass : '');
|
||||||
addBtn.disabled = scope.mode !== 'workspace';
|
addBtn.disabled = scope.mode !== 'workspace';
|
||||||
|
|
|
||||||
|
|
@ -29,5 +29,7 @@
|
||||||
"ui.deleted": "Entry deleted",
|
"ui.deleted": "Entry deleted",
|
||||||
"ui.empty": "No worklog entries yet.",
|
"ui.empty": "No worklog entries yet.",
|
||||||
"ui.edit": "Edit",
|
"ui.edit": "Edit",
|
||||||
"ui.delete": "Delete"
|
"ui.delete": "Delete",
|
||||||
|
"ui.entryCount.one": "{count} entry",
|
||||||
|
"ui.entryCount.many": "{count} entries"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,5 +29,7 @@
|
||||||
"ui.deleted": "Запись удалена",
|
"ui.deleted": "Запись удалена",
|
||||||
"ui.empty": "Записей о работе пока нет.",
|
"ui.empty": "Записей о работе пока нет.",
|
||||||
"ui.edit": "Изменить",
|
"ui.edit": "Изменить",
|
||||||
"ui.delete": "Удалить"
|
"ui.delete": "Удалить",
|
||||||
|
"ui.entryCount.one": "{count} запись",
|
||||||
|
"ui.entryCount.many": "Записей: {count}"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,13 @@
|
||||||
return fallback || key;
|
return fallback || key;
|
||||||
}
|
}
|
||||||
containerEl.__ptCleanup = [];
|
containerEl.__ptCleanup = [];
|
||||||
|
var localizedNodes = [];
|
||||||
|
|
||||||
|
function localized(tag, attrs, key, fallback) {
|
||||||
|
var node = el(tag, attrs, [tr(key, null, fallback)]);
|
||||||
|
localizedNodes.push({ node: node, key: key, fallback: fallback });
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
function trackCleanup(fn) {
|
function trackCleanup(fn) {
|
||||||
if (typeof fn === 'function') {
|
if (typeof fn === 'function') {
|
||||||
|
|
@ -79,12 +86,19 @@
|
||||||
containerEl.__ptCleanup.push(fn);
|
containerEl.__ptCleanup.push(fn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (api.i18n && typeof api.i18n.onDidChangeLocale === 'function') {
|
||||||
|
trackCleanup(api.i18n.onDidChangeLocale(function () {
|
||||||
|
localizedNodes.forEach(function (item) {
|
||||||
|
item.node.textContent = tr(item.key, null, item.fallback);
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
/* ── Header ─────────────────────────────────────────────────── */
|
/* ── Header ─────────────────────────────────────────────────── */
|
||||||
var header = div('pt-header', [
|
var header = div('pt-header', [
|
||||||
span('pt-icon', '◉'),
|
span('pt-icon', '◉'),
|
||||||
div('pt-title-group', [
|
div('pt-title-group', [
|
||||||
el('h2', { className: 'pt-plugin-name' }, [tr('ui.diagnostics', null, 'Platform Diagnostics')]),
|
localized('h2', { className: 'pt-plugin-name' }, 'ui.diagnostics', 'Platform Diagnostics'),
|
||||||
el('p', { className: 'pt-plugin-id' }, [api.pluginId]),
|
el('p', { className: 'pt-plugin-id' }, [api.pluginId]),
|
||||||
]),
|
]),
|
||||||
span('pt-version', 'v' + (props && props.version ? props.version : '0.1.0')),
|
span('pt-version', 'v' + (props && props.version ? props.version : '0.1.0')),
|
||||||
|
|
@ -93,7 +107,7 @@
|
||||||
/* ── Status badge ──────────────────────────────────────────── */
|
/* ── Status badge ──────────────────────────────────────────── */
|
||||||
var badge = div('pt-badge pt-badge-success', [
|
var badge = div('pt-badge pt-badge-success', [
|
||||||
el('span', {}, ['✅']),
|
el('span', {}, ['✅']),
|
||||||
el('span', {}, [tr('ui.bundleLoaded', null, 'Frontend Bundle Loaded')]),
|
localized('span', {}, 'ui.bundleLoaded', 'Frontend Bundle Loaded'),
|
||||||
]);
|
]);
|
||||||
var badgeRow = div('', [badge]);
|
var badgeRow = div('', [badge]);
|
||||||
|
|
||||||
|
|
@ -279,7 +293,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
var bridgeCard = div('pt-card', [
|
var bridgeCard = div('pt-card', [
|
||||||
el('h3', { className: 'pt-card-title' }, [tr('ui.apiBridge', null, 'Real Plugin API Bridge')]),
|
localized('h3', { className: 'pt-card-title' }, 'ui.apiBridge', 'Real Plugin API Bridge'),
|
||||||
el('ul', { className: 'pt-list' }, [
|
el('ul', { className: 'pt-list' }, [
|
||||||
el('li', { className: 'pt-list-item' }, [
|
el('li', { className: 'pt-list-item' }, [
|
||||||
span('pt-list-label', 'Persisted setting'),
|
span('pt-list-label', 'Persisted setting'),
|
||||||
|
|
@ -366,7 +380,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
var testsCard = div('pt-card', [
|
var testsCard = div('pt-card', [
|
||||||
el('h3', { className: 'pt-card-title' }, [tr('ui.testResults', null, 'Test Results')]),
|
localized('h3', { className: 'pt-card-title' }, 'ui.testResults', 'Test Results'),
|
||||||
summaryRow,
|
summaryRow,
|
||||||
testsList,
|
testsList,
|
||||||
]);
|
]);
|
||||||
|
|
@ -403,7 +417,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
var capsCard = div('pt-card', [
|
var capsCard = div('pt-card', [
|
||||||
el('h3', { className: 'pt-card-title' }, [tr('ui.capabilities', null, 'Registered Capabilities')]),
|
localized('h3', { className: 'pt-card-title' }, 'ui.capabilities', 'Registered Capabilities'),
|
||||||
capList,
|
capList,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
@ -426,7 +440,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
var infoCard = div('pt-card', [
|
var infoCard = div('pt-card', [
|
||||||
el('h3', { className: 'pt-card-title' }, [tr('ui.pluginInfo', null, 'Plugin Info')]),
|
localized('h3', { className: 'pt-card-title' }, 'ui.pluginInfo', 'Plugin Info'),
|
||||||
infoList,
|
infoList,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
@ -461,7 +475,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
var apiCard = div('pt-card', [
|
var apiCard = div('pt-card', [
|
||||||
el('h3', { className: 'pt-card-title' }, [tr('ui.hostMethods', null, 'Host API Methods')]),
|
localized('h3', { className: 'pt-card-title' }, 'ui.hostMethods', 'Host API Methods'),
|
||||||
apiStatusList,
|
apiStatusList,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
@ -589,7 +603,7 @@
|
||||||
trackCleanup(function () { stopMouseCapture(); });
|
trackCleanup(function () { stopMouseCapture(); });
|
||||||
|
|
||||||
var mouseCard = div('pt-card', [
|
var mouseCard = div('pt-card', [
|
||||||
el('h3', { className: 'pt-card-title' }, [tr('ui.mouseInspector', null, 'Mouse Event Inspector')]),
|
localized('h3', { className: 'pt-card-title' }, 'ui.mouseInspector', 'Mouse Event Inspector'),
|
||||||
el('p', { style: { margin: '0 0 0.5rem', color: '#a0a0b8', fontSize: '0.8rem' } }, [
|
el('p', { style: { margin: '0 0 0.5rem', color: '#a0a0b8', fontSize: '0.8rem' } }, [
|
||||||
'Captures ALL mouse/pointer events on window. Press back/forward buttons to see what WebKitGTK reports.',
|
'Captures ALL mouse/pointer events on window. Press back/forward buttons to see what WebKitGTK reports.',
|
||||||
]),
|
]),
|
||||||
|
|
@ -676,6 +690,23 @@
|
||||||
if (api && api.i18n && typeof api.i18n.t === 'function') return api.i18n.t(key, params, fallback);
|
if (api && api.i18n && typeof api.i18n.t === 'function') return api.i18n.t(key, params, fallback);
|
||||||
return fallback || key;
|
return fallback || key;
|
||||||
}
|
}
|
||||||
|
var localizedNodes = [];
|
||||||
|
var unsubscribeLocale = null;
|
||||||
|
|
||||||
|
function localized(tag, attrs, key, fallback) {
|
||||||
|
var node = el(tag, attrs, [tr(key, null, fallback)]);
|
||||||
|
localizedNodes.push({ node: node, key: key, fallback: fallback });
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (api.i18n && typeof api.i18n.onDidChangeLocale === 'function') {
|
||||||
|
unsubscribeLocale = api.i18n.onDidChangeLocale(function () {
|
||||||
|
localizedNodes.forEach(function (item) {
|
||||||
|
item.node.textContent = tr(item.key, null, item.fallback);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
containerEl.__ptSettingsCleanup = unsubscribeLocale;
|
||||||
|
}
|
||||||
|
|
||||||
/* ── Counter state (local, not persisted) ──────────────────── */
|
/* ── Counter state (local, not persisted) ──────────────────── */
|
||||||
var counterState = { value: 0 };
|
var counterState = { value: 0 };
|
||||||
|
|
@ -684,7 +715,7 @@
|
||||||
var header = div('pt-header', [
|
var header = div('pt-header', [
|
||||||
span('pt-icon', '⚙️'),
|
span('pt-icon', '⚙️'),
|
||||||
div('pt-title-group', [
|
div('pt-title-group', [
|
||||||
el('h2', { className: 'pt-plugin-name' }, [tr('ui.settings', null, 'Platform Test Settings')]),
|
localized('h2', { className: 'pt-plugin-name' }, 'ui.settings', 'Platform Test Settings'),
|
||||||
el('p', { className: 'pt-plugin-id' }, [api.pluginId]),
|
el('p', { className: 'pt-plugin-id' }, [api.pluginId]),
|
||||||
]),
|
]),
|
||||||
]);
|
]);
|
||||||
|
|
@ -707,24 +738,24 @@
|
||||||
var incrementBtn = el('button', { className: 'btn btn-primary', onClick: function () {
|
var incrementBtn = el('button', { className: 'btn btn-primary', onClick: function () {
|
||||||
counterState.value += 1;
|
counterState.value += 1;
|
||||||
counterDisplay.firstChild.textContent = String(counterState.value);
|
counterDisplay.firstChild.textContent = String(counterState.value);
|
||||||
}}, [tr('ui.increment', null, '+ Increment')]);
|
}}, [localized('span', {}, 'ui.increment', '+ Increment')]);
|
||||||
|
|
||||||
var decrementBtn = el('button', { className: 'btn btn-secondary', onClick: function () {
|
var decrementBtn = el('button', { className: 'btn btn-secondary', onClick: function () {
|
||||||
counterState.value = Math.max(0, counterState.value - 1);
|
counterState.value = Math.max(0, counterState.value - 1);
|
||||||
counterDisplay.firstChild.textContent = String(counterState.value);
|
counterDisplay.firstChild.textContent = String(counterState.value);
|
||||||
}}, [tr('ui.decrement', null, '− Decrement')]);
|
}}, [localized('span', {}, 'ui.decrement', '− Decrement')]);
|
||||||
|
|
||||||
var resetBtn = el('button', { className: 'btn btn-secondary', onClick: function () {
|
var resetBtn = el('button', { className: 'btn btn-secondary', onClick: function () {
|
||||||
counterState.value = 0;
|
counterState.value = 0;
|
||||||
counterDisplay.firstChild.textContent = '0';
|
counterDisplay.firstChild.textContent = '0';
|
||||||
}}, [tr('ui.reset', null, '↺ Reset')]);
|
}}, [localized('span', {}, 'ui.reset', '↺ Reset')]);
|
||||||
|
|
||||||
var btnGroup = el('div', { style: { display: 'flex', gap: '0.5rem' } }, [
|
var btnGroup = el('div', { style: { display: 'flex', gap: '0.5rem' } }, [
|
||||||
incrementBtn, decrementBtn, resetBtn,
|
incrementBtn, decrementBtn, resetBtn,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
var counterCard = div('pt-card', [
|
var counterCard = div('pt-card', [
|
||||||
el('h3', { className: 'pt-card-title' }, [tr('ui.counter', null, 'Interactive Counter (Local State)')]),
|
localized('h3', { className: 'pt-card-title' }, 'ui.counter', 'Interactive Counter (Local State)'),
|
||||||
counterDisplay,
|
counterDisplay,
|
||||||
btnGroup,
|
btnGroup,
|
||||||
el('p', { style: { marginTop: '0.75rem', color: '#6c6c8a', fontSize: '0.7rem' } }, [
|
el('p', { style: { marginTop: '0.75rem', color: '#6c6c8a', fontSize: '0.7rem' } }, [
|
||||||
|
|
@ -750,7 +781,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
var settingsCard = div('pt-card', [
|
var settingsCard = div('pt-card', [
|
||||||
el('h3', { className: 'pt-card-title' }, [tr('ui.demoSettings', null, 'Plugin Settings (Demo)')]),
|
localized('h3', { className: 'pt-card-title' }, 'ui.demoSettings', 'Plugin Settings (Demo)'),
|
||||||
settingsDemoList,
|
settingsDemoList,
|
||||||
el('p', { style: { marginTop: '0.5rem', color: '#6c6c8a', fontSize: '0.7rem' } }, [
|
el('p', { style: { marginTop: '0.5rem', color: '#6c6c8a', fontSize: '0.7rem' } }, [
|
||||||
'Use api.settings.read() / api.settings.write() for persisted settings.',
|
'Use api.settings.read() / api.settings.write() for persisted settings.',
|
||||||
|
|
@ -765,8 +796,10 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
unmount: function (containerEl) {
|
unmount: function (containerEl) {
|
||||||
|
if (typeof containerEl.__ptSettingsCleanup === 'function') containerEl.__ptSettingsCleanup();
|
||||||
containerEl.innerHTML = '';
|
containerEl.innerHTML = '';
|
||||||
containerEl.className = '';
|
containerEl.className = '';
|
||||||
|
delete containerEl.__ptSettingsCleanup;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -423,7 +423,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteSecret(id) {
|
function deleteSecret(id) {
|
||||||
if (!id || !window.confirm('Delete this secret?')) return;
|
if (!id || !window.confirm(tr('ui.deleteConfirm', null, 'Delete this secret?'))) return;
|
||||||
api.secrets.delete(id).then(function () {
|
api.secrets.delete(id).then(function () {
|
||||||
selectedID = '';
|
selectedID = '';
|
||||||
selectedRecord = null;
|
selectedRecord = null;
|
||||||
|
|
@ -437,7 +437,7 @@
|
||||||
function copySecretLink(id) {
|
function copySecretLink(id) {
|
||||||
api.secrets.copyLink(id).then(function (link) {
|
api.secrets.copyLink(id).then(function (link) {
|
||||||
return writeClipboard(api, link).then(function () {
|
return writeClipboard(api, link).then(function () {
|
||||||
setStatus('Secret link copied', false);
|
setStatus(tr('ui.linkCopied', null, 'Secret link copied'), false);
|
||||||
});
|
});
|
||||||
}).catch(function (err) {
|
}).catch(function (err) {
|
||||||
setStatus((err && err.message) ? err.message : String(err), true);
|
setStatus((err && err.message) ? err.message : String(err), true);
|
||||||
|
|
|
||||||
|
|
@ -32,5 +32,7 @@
|
||||||
"ui.scope": "Scope",
|
"ui.scope": "Scope",
|
||||||
"ui.value": "Value",
|
"ui.value": "Value",
|
||||||
"ui.save": "Save",
|
"ui.save": "Save",
|
||||||
"ui.cancel": "Cancel"
|
"ui.cancel": "Cancel",
|
||||||
|
"ui.deleteConfirm": "Delete this secret?",
|
||||||
|
"ui.linkCopied": "Secret link copied"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,5 +32,7 @@
|
||||||
"ui.scope": "Область",
|
"ui.scope": "Область",
|
||||||
"ui.value": "Значение",
|
"ui.value": "Значение",
|
||||||
"ui.save": "Сохранить",
|
"ui.save": "Сохранить",
|
||||||
"ui.cancel": "Отмена"
|
"ui.cancel": "Отмена",
|
||||||
|
"ui.deleteConfirm": "Удалить этот секрет?",
|
||||||
|
"ui.linkCopied": "Ссылка на секрет скопирована"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,15 @@ class FakeNode {
|
||||||
addEventListener() {}
|
addEventListener() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function findByClass(node, className) {
|
||||||
|
if (String(node.className || '').split(/\s+/).includes(className)) return node;
|
||||||
|
for (const child of node.children || []) {
|
||||||
|
const found = findByClass(child, className);
|
||||||
|
if (found) return found;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
function makeDocument() {
|
function makeDocument() {
|
||||||
return {
|
return {
|
||||||
head: new FakeNode('head'),
|
head: new FakeNode('head'),
|
||||||
|
|
@ -76,6 +85,25 @@ if (!components) {
|
||||||
|
|
||||||
const api = {
|
const api = {
|
||||||
pluginId: 'verstak.platform-test',
|
pluginId: 'verstak.platform-test',
|
||||||
|
i18n: {
|
||||||
|
locale: 'en',
|
||||||
|
listeners: new Set(),
|
||||||
|
messages: {
|
||||||
|
en: { 'ui.diagnostics': 'Platform Diagnostics', 'ui.settings': 'Platform Test Settings' },
|
||||||
|
ru: { 'ui.diagnostics': 'Диагностика платформы', 'ui.settings': 'Настройки теста платформы' },
|
||||||
|
},
|
||||||
|
getLocale() { return this.locale; },
|
||||||
|
t(key, params, fallback) { return this.messages[this.locale][key] || fallback || key; },
|
||||||
|
onDidChangeLocale(listener) {
|
||||||
|
this.listeners.add(listener);
|
||||||
|
listener(this.locale);
|
||||||
|
return () => this.listeners.delete(listener);
|
||||||
|
},
|
||||||
|
setLocale(locale) {
|
||||||
|
this.locale = locale;
|
||||||
|
this.listeners.forEach((listener) => listener(locale));
|
||||||
|
},
|
||||||
|
},
|
||||||
settings: {
|
settings: {
|
||||||
read: async () => 'initial value',
|
read: async () => 'initial value',
|
||||||
write: async () => undefined,
|
write: async () => undefined,
|
||||||
|
|
@ -179,9 +207,27 @@ const api = {
|
||||||
if (container.children.length === 0) {
|
if (container.children.length === 0) {
|
||||||
throw new Error(`${name} mounted no DOM nodes`);
|
throw new Error(`${name} mounted no DOM nodes`);
|
||||||
}
|
}
|
||||||
|
if (name === 'DiagnosticsPanel') {
|
||||||
|
api.i18n.setLocale('ru');
|
||||||
|
if (findByClass(container, 'pt-plugin-name')?.textContent !== 'Диагностика платформы') {
|
||||||
|
throw new Error('DiagnosticsPanel did not update after locale change');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (name === 'PlatformTestSettings') {
|
||||||
|
const counter = findByClass(container, 'pt-counter-value');
|
||||||
|
counter.textContent = '3';
|
||||||
|
api.i18n.setLocale('ru');
|
||||||
|
if (findByClass(container, 'pt-plugin-name')?.textContent !== 'Настройки теста платформы') {
|
||||||
|
throw new Error('PlatformTestSettings did not update after locale change');
|
||||||
|
}
|
||||||
|
if (counter.textContent !== '3') {
|
||||||
|
throw new Error('PlatformTestSettings lost counter state after locale change');
|
||||||
|
}
|
||||||
|
}
|
||||||
if (typeof component.unmount === 'function') {
|
if (typeof component.unmount === 'function') {
|
||||||
component.unmount(container);
|
component.unmount(container);
|
||||||
}
|
}
|
||||||
|
api.i18n.setLocale('en');
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('platform-test frontend smoke passed');
|
console.log('platform-test frontend smoke passed');
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue