// Generated, do not edit. sha256:bf3b89b4669e19b78df9f4741f695e6025ab616c2c0a5f205b84e84c1ce21f92 import * as db from '../db.js'; import { ASSET_DEFINITIONS, DASHBOARD } from '../../shared/config.js'; import { toSearchName } from '../../shared/search-name.js'; import { getPref, setPref } from './preferences.js'; import { createAsset } from './assets.js'; import { createAccount } from './accounts.js'; import { activeProfile, addWidget, listWidgets } from './dashboard.js'; import { currentCount, capacityReachedFor } from './_limits.js'; export function setupStatus() { const done = Number(getPref('app', 'setup_done')) === 1; const empty = currentCount('assets') === 0; const own = db.one(`SELECT (SELECT COUNT(*) FROM Account) + (SELECT COUNT(*) FROM Event) + (SELECT COUNT(*) FROM Valuation) AS n`).n; return { needed: !done && empty, done, empty, persona: getPref('app', 'persona'), currencyOpen: !done && empty && own === 0 }; } function assertKnownAsset(symbol) { if (!ASSET_DEFINITIONS[symbol]) { throw new Error(`Unknown asset '${symbol}'. Allowed: ${Object.keys(ASSET_DEFINITIONS).join(', ')}.`); } } async function ensureAsset(symbol) { const def = ASSET_DEFINITIONS[symbol]; const existing = db.one(`SELECT id FROM Asset WHERE symbol = ?`, [def.symbol]); if (existing) return existing.id; return capacityReachedFor('assets') === null ? createAsset(def) : null; } async function ensureAccount({ name, kind }) { const existing = db.one(`SELECT id FROM Account WHERE searchName = ?`, [toSearchName(name)]); if (existing) return existing.id; if (kind === 'bank' && capacityReachedFor('fiatAccounts') !== null) return null; const own = kind === 'wallet' || kind === 'vault'; return createAccount({ name, kind, isOwnCustody: own, scanEnabled: false, taxCategory: null }); } const SETUP_SPAN = 4; function placeInFreeSpace(rows, items) { const cols = DASHBOARD.GRID_COLUMNS; const heightOf = (type, h) => (h > 0 ? h : DASHBOARD.WIDGETS[type]?.defaultH || 1); const bottom = new Array(cols).fill(0); for (const r of rows) { const end = r.gridY + heightOf(r.type, r.spanHeight); for (let c = r.gridX; c < Math.min(cols, r.gridX + r.spanWidth); c++) bottom[c] = Math.max(bottom[c], end); } return items.map(({ prefer, ...w }) => { const span = w.spanWidth ?? DASHBOARD.WIDGETS[w.type].defaultSpan; let bestX = 0, bestY = Infinity; for (let x = 0; x + span <= cols; x++) { const y = Math.max(...bottom.slice(x, x + span)); if (y < bestY || (y === bestY && x === prefer)) { bestY = y; bestX = x; } } for (let c = bestX; c < bestX + span; c++) bottom[c] = bestY + heightOf(w.type, null); return { ...w, gridX: bestX, gridY: bestY }; }); } export async function completeSetup({ assets = [], persona = 'broad', accounts = [], widgets = [] } = {}) { assets.forEach(assertKnownAsset); await setPref('app', 'persona', persona); const assetIds = []; for (const s of assets) { const id = await ensureAsset(s); if (id != null) assetIds.push(id); } let accountCount = 0; for (const a of accounts) if ((await ensureAccount(a)) != null) accountCount++; const profileId = activeProfile().id; const add = []; if (widgets.includes('standing')) add.push({ type: 'standing', prefer: 4 }); if (widgets.includes('signal') && persona === 'bitcoin') add.push({ type: 'signal', prefer: 4 }); if (widgets.includes('spot')) assetIds.forEach(id => add.push({ type: 'spot', instanceKey: `spot-${id}`, assetId: id, prefer: 0, settings: { momentum: false }, spanWidth: SETUP_SPAN })); let widgetCount = 0; for (const w of placeInFreeSpace(listWidgets(profileId), add)) if (await addWidget(profileId, w)) widgetCount++; await setPref('app', 'setup_done', 1); return { persona, assetIds, accounts: accountCount, widgets: widgetCount }; }