UNPKG

@opengis/admin

Version:

This project Softpro Admin

125 lines (96 loc) 5.15 kB
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 = {}, user = {}, }) { const { name } = params; const { granularity = 'month' } = query; 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 }; }