mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-28 19:01:34 +00:00
95 lines
4.5 KiB
JavaScript
95 lines
4.5 KiB
JavaScript
// «Уже загруженные»: план, который не удаляется за ненадобностью, обязан быть
|
|
// находимым. Иначе обещание «отцепил — файл остался» неполноценно: вернуть его
|
|
// из карточки было нельзя, старый URL нигде не хранится (HP-1466-02).
|
|
// Заодно это единственный способ удалить план — явным действием.
|
|
import { launch, checkAll, finish } from './serve.mjs';
|
|
const { page, browser } = await launch({ width: 900, height: 1000 }, 1);
|
|
const res = await page.evaluate(async () => {
|
|
const out = {};
|
|
const c = window.__card;
|
|
const sr = () => c.shadowRoot || c.renderRoot;
|
|
const base = c.hass.callWS;
|
|
|
|
let serverPlans = [
|
|
{ name: 'f1.aaa.png', url: '/api/houseplan/content/plans/_/f1.aaa.png', size: 121335, modified: 2, used_by: [] },
|
|
{ name: 'f2.bbb.png', url: '/api/houseplan/content/plans/_/f2.bbb.png', size: 26931, modified: 1, used_by: ['2 этаж'] },
|
|
];
|
|
const deleted = [];
|
|
c.hass = { ...c.hass, callWS: async (m) => {
|
|
if (m.type === 'houseplan/plans/list') return { plans: serverPlans };
|
|
if (m.type === 'houseplan/plans/delete') {
|
|
const p = serverPlans.find((x) => x.name === m.name);
|
|
if (p?.used_by.length) { const e = new Error('in_use'); e.code = 'in_use'; throw e; }
|
|
deleted.push(m.name);
|
|
serverPlans = serverPlans.filter((x) => x.name !== m.name);
|
|
return { ok: true, removed: true };
|
|
}
|
|
if (m.type === 'houseplan/content/sign') {
|
|
const urls = {}; for (const p of m.paths) urls[p] = p + '?authSig=X'; return { urls };
|
|
}
|
|
return base(m);
|
|
} };
|
|
// пространство без плана — как после отцепления
|
|
c._openSpaceDialog('edit', 'f1'); await c.updateComplete;
|
|
c._spaceDialog = { ...c._spaceDialog, source: 'file', planUrl: null, planFile: null };
|
|
await c.updateComplete;
|
|
out.saveBlockedWithoutPlan = !!sr().querySelector('hp-dialog .btn.on[disabled]');
|
|
|
|
// открываем список сохранённых
|
|
await c._toggleServerPlans();
|
|
await new Promise((r) => setTimeout(r, 60));
|
|
await c.updateComplete;
|
|
const rows = [...sr().querySelectorAll('.savedplan')];
|
|
out.listed = rows.length;
|
|
out.showsUsage = (rows[1]?.textContent || '').includes('2 этаж');
|
|
out.deleteDisabledForUsed = !!rows[1]?.querySelector('.btn.danger[disabled]');
|
|
out.deleteEnabledForFree = !rows[0]?.querySelector('.btn.danger[disabled]');
|
|
out.thumbnailSigned = (rows[0]?.querySelector('img')?.getAttribute('src') || '').includes('authSig=');
|
|
|
|
// выбираем свободный план — он подставляется в диалог
|
|
c._useServerPlan(serverPlans[0].url);
|
|
await new Promise((r) => setTimeout(r, 80));
|
|
await c.updateComplete;
|
|
out.picked = c._spaceDialog.planUrl === '/api/houseplan/content/plans/_/f1.aaa.png';
|
|
out.listClosed = !c._spaceDialog.pickSaved;
|
|
out.saveEnabledAfterPick = !sr().querySelector('hp-dialog .btn.on[disabled]');
|
|
|
|
// выбранный в этом же диалоге удалить нельзя: сохранение записало бы ссылку
|
|
// на несуществующий файл (HP-1470-02)
|
|
await c._toggleServerPlans();
|
|
await new Promise((r) => setTimeout(r, 60));
|
|
await c.updateComplete;
|
|
const rows2 = [...sr().querySelectorAll('.savedplan')];
|
|
const picked = rows2.find((r) => r.textContent.includes('f1.aaa.png'));
|
|
out.deleteDisabledForPicked = !!picked?.querySelector('.btn.danger[disabled]');
|
|
c._spaceDialog = { ...c._spaceDialog, planUrl: null };
|
|
await c.updateComplete;
|
|
await c._deleteServerPlan('f2.bbb.png').catch(() => {});
|
|
out.usedNotDeleted = !deleted.includes('f2.bbb.png');
|
|
const deleting = c._deleteServerPlan('f1.aaa.png');
|
|
await c.updateComplete;
|
|
sr().querySelector('hp-confirm .danger-confirm-footer .btn.danger')?.click();
|
|
await deleting;
|
|
await c.updateComplete;
|
|
out.freeDeleted = deleted.includes('f1.aaa.png');
|
|
out.rowGone = !(c._spaceDialog.saved || []).some((p) => p.name === 'f1.aaa.png');
|
|
return out;
|
|
});
|
|
// зафиксировано прогоном на v1.47.0 и сверено с кодом
|
|
checkAll(res, {
|
|
saveBlockedWithoutPlan: true,
|
|
listed: 2,
|
|
showsUsage: true,
|
|
deleteDisabledForUsed: true,
|
|
deleteEnabledForFree: true,
|
|
thumbnailSigned: true,
|
|
picked: true,
|
|
listClosed: true,
|
|
saveEnabledAfterPick: true,
|
|
deleteDisabledForPicked: true,
|
|
usedNotDeleted: true,
|
|
freeDeleted: true,
|
|
rowGone: true,
|
|
});
|
|
await finish(browser);
|