UNPKG

@opengis/bi

Version:

BI data visualization module

118 lines (97 loc) 4.88 kB
import { getTemplate, getPGAsync, pgClients, getMeta } from '@opengis/fastify-table/utils.js'; import mdToHTML from '../helpers/mdToHTML.js'; async function getWidget({ pg: pg1 = pgClients.client, dashboard, widget }) { if (!dashboard && !widget) { return { message: `not enough params: dashboard / widget`, status: 400 }; } const dashboardData = dashboard ? await getTemplate('dashboard', dashboard) : null; const dashboardData1 = await pg1.query(`select db, table_name, widgets as "dashboardWidgets" from bi.dashboard where dashboard_id=$1`, [dashboard]) .then(el => el.rows?.[0] || {}); const { dashboardWidgets = [] } = dashboardData1; const dashboardDb = typeof dashboardData1?.db === 'string' && dashboardData1?.db?.startsWith('{') ? JSON.parse(dashboardData1?.db) : dashboardData1?.db; const dashboardIndex = dashboardData?.find((el) => el[0] == 'index.yml')?.[1]; // dashboardData?.find((el) => el[2] == 'index')?.[1] const pg = dashboardDb || dashboardIndex?.db ? await getPGAsync(dashboardDb || dashboardIndex?.db) : pg1; const { id, tableName } = !dashboardData && !dashboardData1 && pg.pk['bi.dashboard'] && dashboard ? await pg1.query(`select dashboard_id as id, table_name as "tableName" from bi.dashboard where $1 in (dashboard_id, name)`, [dashboard]) .then(el => el.rows?.[0] || {}) : {}; if (!dashboardData && !dashboardData1 && dashboard && !id) { return { message: `dashboard not found: ${dashboard}`, status: 404 }; } dashboardData?.forEach((el) => { el[2] = el[0].split('.')[0]; }); const widgetData = dashboard ? dashboardData?.find((el) => el[2] === (widget || 'index'))?.[1] || dashboardWidgets?.find(el => el.name === widget) : await getTemplate('widget', widget); if (typeof widgetData === 'string' || typeof widgetData?.html === 'string' || (widgetData?.type === 'text' && typeof widgetData?.data?.text === 'string')) { const html = widgetData?.html || mdToHTML(widgetData?.data?.text || widgetData); return { source: html, status: 200 }; } if (!id && !dashboardData && !dashboardData1 && !widgetData) { return { message: `not found ${widget} ${dashboard}`, status: 404 }; } const q = `select *, title as text, coalesce(data::jsonb, '{}'::jsonb) || jsonb_build_object('table', table_name) as data from bi.widget where dashboard_id=$1 and name=$2`; const { type, text, data = {}, controls, style, options, yml } = widgetData || (await pg .query(q, [id || dashboard, widget]) .then(el => el.rows?.[0] || {})); if (!type) { return { message: `widget not found: ${widget}`, status: 404 }; } Object.assign(data, { table: data.table || tableName || widgetData?.table_name || dashboardIndex?.table || dashboardIndex?.table_name || dashboardData1?.table_name, db: dashboardDb?.db || dashboardDb || dashboardIndex?.db || widgetData?.db || pg?.options?.database, }); const main = { ...(dashboardIndex || {}), ...widgetData, ...data, ...data?.data || {} }; const widgetDb = widgetData?.db ? await getPGAsync(widgetData?.db) : pg; if (!main?.table) { return { message: /* json.error || */ `invalid ${widget ? 'widget' : 'dashboard'}: empty table`, status: 404, }; } const loadTemplate = pg.pk?.['admin.doc_template'] ? await pg.query( 'select body from admin.doc_template where doc_type=5 and title=$1', [main.table] ).then(el => el.rows?.[0]?.body) : null; const { pk, view, columns = [] } = await getMeta({ pg: widgetDb, table: loadTemplate?.table || main?.table }); if (!pk && !view) { return { message: /* json.error || */ `invalid ${widget ? 'widget' : 'dashboard'}: table not found (${loadTemplate?.table || main?.table})`, status: 404, }; } const tableSQL = main?.tableSQL?.map( (el, i) => `left join lateral(${el})t${i + 1} on 1=1` ); const columnList = columns.map(col => col.name); const res = { ...main, pg: widgetDb, sql: widgetData?.sql, limit: widgetData?.limit, tableSQL, data, type, text, controls, style, options, yml }; if (res.x && !columnList.includes(res.x) && !loadTemplate?.table && !tableSQL?.join()?.includes(res.x)) { Object.assign(res, { x: null, error: `column does not exists: ${res.x} at table ${res.table}` }); } if (loadTemplate?.table) { Object.assign(res.data || {}, { table: loadTemplate?.table }); Object.assign(res, { table: loadTemplate?.table, table_name: loadTemplate?.table, tableSQL: loadTemplate.sql?.filter?.(el => !el.disabled && el?.sql?.replace)?.map?.((el, i) => `left join lateral(${el.sql})t${i + 1} on 1=1`)?.join?.(' ') }); } return res; } export default getWidget;