@opengis/admin
Version:
This project Softpro Admin
126 lines (97 loc) • 5.2 kB
JavaScript
import { getMeta, getTemplate, pgClients, handlebarsSync } from '@opengis/fastify-table/utils.js';
const isValidDate = (dateStr) => (new Date(dateStr)).toString() !== 'Invalid Date';
export default async function calendarData({
pg = pgClients.client, params = {}, query = {}, session = {},
}) {
const { name } = params;
const { granularity = 'month' } = query;
const { user = {} } = session.passport || {};
if (!name) {
return { message: 'not enough params: name', status: 400 };
}
if (query.granularity && !['day', 'month', 'week', 'year'].includes(granularity)) {
return { message: 'invalid query params: granularity', status: 400 };
}
const body = await getTemplate('calendar', name);
if (!body) {
return { message: `calendar not found: ${name}`, status: 404 };
}
const {
title,
table,
meta = {},
} = body || {};
if (!table) {
return { message: 'not enough calendar params: table', status: 404 };
}
if (!pg.pk?.[table]) {
return { message: `table pkey not found: ${table}`, status: 404 };
}
const filterList = (body?.filter || [])
.concat(body?.filterInline || [])
.concat(body?.filterCustom || [])
.concat(body?.filterState || [])
.concat(body?.filterList || [])
.concat(body?.filters || [])
.concat(body?.filter_list || []);
const { columns = [] } = await getMeta({ pg, table });
const columnList = columns?.map((el) => el?.name);
const dateColumn = columns?.find((el) => el?.name === (meta?.date || meta?.start))?.name
|| columns?.find((el) => el?.name === 'cdate')?.name;
if (query.date && !dateColumn) {
return { message: 'invalid template params: date column not found', status: 400 };
}
if (query.date && !isValidDate(query.date)) {
return { message: 'Invalid date: out of range or incorrect format', status: 400 };
}
const filterWhere = filterList?.length && query.filter?.length
? filterList
.filter((el) => (Object.hasOwn(el, 'enabled') ? el?.enabled : true))
.map((el) => {
const val = query.filter.split(',').find((e) => e?.split('=')?.shift()?.includes(el.column || el.name))?.split('=')?.pop();
if (val) return el.column && val ? `(${[`${el.column}::text='${val.replace(/'/g, "''")}'::text`, el.query].filter((el) => el).join(' and ')})` : el.query;
})
.filter((el) => el)
.join(' and ')
: undefined;
const queryWhere = handlebarsSync.compile(body.query || '1=1')({ user, uid: user?.uid });
const filterDate = query.date ? `date_trunc('${granularity}', "${dateColumn}"::date)='${query.date}'::date` : undefined;
const where = [queryWhere, filterDate, filterWhere].filter((el) => el).join(' and ');
const filtersByColumn = filterList.filter((el) => (Object.hasOwn(el, 'enabled') ? el?.enabled : true) && el?.column);
const filters = [];
if (filtersByColumn?.length) {
await Promise.all(filtersByColumn.map(async (el) => {
const { rows: filterData = [] } = await pg.query(`select ${el.column.replace(/'/g, "''")} as id, count(*) from ${table}
where ${el.query || '1=1'} and ${filterWhere || '1=1'} group by ${el.column.replace(/'/g, "''")}`);
if (!filterData?.length) return;
const clsData = await getTemplate(['cls', 'select'], el.cls);
if (!el.cls || !clsData?.length) {
filterData.forEach((item) => filters.push(item));
return;
}
filterData.forEach((filter) => {
const cls = clsData.find((item) => item.id === filter.id.toString());
Object.assign(filter, { title: cls?.text, color: cls?.color });
filters.push(filter);
});
}));
}
const filtersByPreparedQuery = filterList.filter((el) => (Object.hasOwn(el, 'enabled') ? el?.enabled : true) && !el?.column && el?.query);
if (filtersByPreparedQuery?.length) {
await Promise.all(filtersByPreparedQuery.map(async (el) => {
const { rows = [] } = await pg.query(`select ${el.query} as id, count(*) from ${table}
where ${filterWhere || '1=1'} group by ${el.query}`);
rows.forEach((item) => filters.push(item));
}));
}
const metaColumns = Object.keys(meta)
.filter((el) => ['date', 'start', 'end', 'title', 'status'].includes(el) && columnList.includes(meta[el]))
.map((el) => `"${meta[el]}" as ${el}`);
if (!metaColumns?.length) {
return { message: `calendar param meta is invalid: invalid/empty keys`, status: 404 };
}
const q = `select ${metaColumns.join(',')} from ${table} where ${where}`;
if (query?.sql && user?.user_type?.includes('admin')) return q;
const { rows = [] } = await pg.query(q);
return { title, filters, granularity, sql: user?.user_type?.includes('admin') ? q : undefined, rows };
}