ui: progressive table render + load timer, v1.3.34

This commit is contained in:
“Naeel”
2026-05-03 17:34:07 +04:00
parent f85027e986
commit 4ecaa508ea
4 changed files with 99 additions and 8 deletions
+1 -1
View File
@@ -52,7 +52,7 @@ spec:
serviceAccountName: fission-console
containers:
- name: console
image: naeel/fission-console:v1.3.33
image: naeel/fission-console:v1.3.34
imagePullPolicy: Always
ports:
- containerPort: 8090
+2 -2
View File
@@ -100,7 +100,7 @@
<div class="nubes">NUBES</div>
<div class="product">FISSION CONSOLE</div>
</div>
<div style="font-size:0.65rem; color:var(--text-secondary); margin-left:10px; align-self:center; opacity:0.7;">v1.3.33</div>
<div style="font-size:0.65rem; color:var(--text-secondary); margin-left:10px; align-self:center; opacity:0.7;">v1.3.34</div>
</div>
<div class="row" style="margin:0;">
<button class="btn ghost" onclick="reloadAll()">Refresh</button>
@@ -398,7 +398,7 @@
</div>
<div class="actions" style="justify-content:space-between; align-items:center;">
<span style="font-size:0.75rem; color:var(--text-secondary);">v1.3.33</span>
<span style="font-size:0.75rem; color:var(--text-secondary);">v1.3.34</span>
<button class="btn ghost" onclick="closeHelp()">Закрыть</button>
</div>
</div>
+30 -5
View File
@@ -1,6 +1,12 @@
/* app.js — основная логика: загрузка данных, таблица функций */
async function reloadAll() {
const progress = startTimedStatus('Загрузка...', 'Загрузка данных', null);
// Показываем таблицу сразу с placeholder'ом
document.getElementById('fn-rows').innerHTML =
'<tr><td colspan="9" style="color:var(--text-secondary); font-style:italic;">⏳ Загружаем функции...</td></tr>';
try {
const [envs, pkgs, fns, http, times] = await Promise.all([
getJSON(API_BASE + '/environments'),
@@ -23,7 +29,7 @@ async function reloadAll() {
return t && t.spec && t.spec.functionref && t.spec.functionref.name;
}).filter(Boolean)).size);
const rows = (fns || []).map(function (f) {
function makeFnRow(f) {
const spec = f.spec || {};
const meta = f.metadata || {};
const ann = meta.annotations || {};
@@ -57,14 +63,33 @@ async function reloadAll() {
'<td>' + cronCell + '</td>' +
'<td class="nowrap">' + actions + '</td>' +
'</tr>';
}).join('');
}
document.getElementById('fn-rows').innerHTML = rows || '<tr><td colspan="9">Нет функций</td></tr>';
if (!rows) {
var fnList = fns || [];
if (fnList.length === 0) {
progress.stop('Загружено: нет функций', '');
document.getElementById('fn-rows').innerHTML = '<tr><td colspan="9">Нет функций</td></tr>';
} else {
// Рендерим первую строку сразу — убираем placeholder
var tbody = document.getElementById('fn-rows');
tbody.innerHTML = makeFnRow(fnList[0]);
// Остальные добавляем по одной с небольшой задержкой
var i = 1;
function appendNext() {
if (i >= fnList.length) {
progress.stop('Загружено ' + fnList.length + ' функций', 'ok');
return;
}
var tr = document.createElement('tbody');
tr.innerHTML = makeFnRow(fnList[i]);
tbody.appendChild(tr.firstChild);
i++;
setTimeout(appendNext, 40);
}
setTimeout(appendNext, 40);
}
} catch (e) {
document.getElementById('fn-rows').innerHTML = '<tr><td colspan="9">Load error: ' + e.message + '</td></tr>';
showStatus('Ошибка загрузки: ' + e.message, 'err');
progress.stop('Ошибка загрузки: ' + e.message, 'err');
}
}
+66
View File
@@ -0,0 +1,66 @@
# Загрузка страницы — flow (май 2026)
## Последовательность при открытии/перезагрузке
```
1. HTML загружен, JS инициализирован
2. checkAuth() (auth.js)
├── localStorage["auth_token"] отсутствует → showLoginOverlay() → СТОП
└── токен есть → setUserAvatar() → hideLoginOverlay() → reloadAll()
3. reloadAll() (app.js)
├── показывает в статусе "Загрузка... Nс" (startTimedStatus, тикает каждую секунду)
├── показывает в таблице "⏳ Загружаем функции..."
├── запускает 5 параллельных запросов (Promise.all):
│ GET /console/api/environments
│ GET /console/api/packages
│ GET /console/api/functions ← обычно самый долгий
│ GET /console/api/httptriggers
│ GET /console/api/timetriggers
└── (ждём ответа... может занять 3–10с при cold start)
4. Данные получены
├── обновляем счётчики (envs, pkgs, fns, http, cron)
├── рендерим ПЕРВУЮ строку функций немедленно
├── остальные строки добавляем по одной каждые 40мс (setTimeout)
└── по завершении статус: "Загружено N функций за Xс"
```
## Путь через doLogin() (при ручном входе)
После успешного POST /console/api/auth:
1. Сохраняем токен в localStorage
2. Проверяем GET /console/api/ns/status
- `ready: false``pollNSStatus()` → показывается init-overlay с прогрессом по стадиям
- `ready: true` → сразу `reloadAll()`
## Почему долго
При первой загрузке после простоя:
- Fission `poolmgr` может не иметь прогретых пулов → холодный старт на first request к каждому language env
- Kubernetes API (~k8s list всех функций, пакетов) — несколько сотен мс при большом числе объектов
- `Promise.all` ждёт самый долгий запрос
## Что показывается пользователю (v1.3.34+)
| Момент | Что видит |
|---|---|
| Сразу при запуске | Таблица: "⏳ Загружаем функции..." |
| Каждую секунду | Статус: "Загрузка данных Nс" |
| Первая функция пришла | Первая строка таблицы появляется |
| +40мс × N | Строки добавляются одна за другой |
| Конец | Статус: "Загружено N функций за Xс" |
## Файлы
| Файл | Роль |
|---|---|
| `ui/js/auth.js``checkAuth()` | Точка входа при загрузке страницы |
| `ui/js/auth.js``doLogin()` | Ручной вход, проверка NS status |
| `ui/js/app.js``reloadAll()` | Загрузка данных, построчный рендер |
| `ui/js/init.js``pollNSStatus()` | Ожидание готовности namespace (init overlay) |
| `ui/js/init.js``startTimedStatus()` | Таймер в статус-баре |