@opengis/bi
Version:
BI data visualization module
118 lines (97 loc) • 4.88 kB
JavaScript
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;