@opengis/admin 0.3.101 → 0.3.102
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
@@ -6,7 +6,7 @@ import getFilterQuery from '../utils/getFilterQuery.js';
|
|
6
6
|
|
7
7
|
const maxLimit = 100;
|
8
8
|
|
9
|
-
export default async function
|
9
|
+
export default async function tableData({
|
10
10
|
pg = pgClients.client, params = {}, query = {}, user = {},
|
11
11
|
}, reply) {
|
12
12
|
if (!params?.name) {
|
@@ -33,7 +33,7 @@ export default async function reportData({
|
|
33
33
|
|
34
34
|
const { uid } = user;
|
35
35
|
|
36
|
-
const { widgets = [], kpi, sql = `select * from ${loadTemplate.table} where ${loadTemplate.query || 'true'}`, meta, filters } = loadTemplate;
|
36
|
+
const { title, subtitle, widgets = [], kpi, sql = `select * from ${loadTemplate.table} where ${loadTemplate.query || 'true'}`, meta, filters } = loadTemplate;
|
37
37
|
const { date, columns: metaColumns } = meta || {};
|
38
38
|
|
39
39
|
const granularity = query.granularity && date && false ? `date_trunc('${query.granularity}',${date})::date::text` : null;
|
@@ -45,7 +45,7 @@ export default async function reportData({
|
|
45
45
|
const limit = Math.min(maxLimit, +(query.limit || 20));
|
46
46
|
const offset = query.page && query.page > 0 ? (query.page - 1) * limit : 0;
|
47
47
|
|
48
|
-
const kpiColumns = kpi ? kpi?.filter?.(el => el.agg)?.map?.(el => `${el.agg || 'count(*)'} as
|
48
|
+
const kpiColumns = kpi ? kpi?.filter?.(el => el.agg)?.map?.(el => `${el.agg || 'count(*)'} as value`)?.join?.(',') : '';
|
49
49
|
const columnsList = metaColumns;
|
50
50
|
|
51
51
|
const qMeta = await handlebars.compile(sql)({ user, uid });
|
@@ -63,7 +63,7 @@ export default async function reportData({
|
|
63
63
|
const kpiData = await pg.query(qAgg).then(el => el.rows?.[0] || {}).catch(err => {
|
64
64
|
return reply.status(500).send('kpi error: ' + err.toString());
|
65
65
|
});
|
66
|
-
kpi?.filter?.(el => el.agg)?.forEach?.(el => Object.assign(el, { count: kpiData[el.name] || 0 }));
|
66
|
+
kpi?.filter?.(el => el.agg)?.forEach?.(el => Object.assign(el, { count: kpiData[el.name] || 0, agg: user?.user_type === 'admin' ? el.agg : undefined }));
|
67
67
|
|
68
68
|
if (kpi?.filter?.(el => el.sql)?.length) {
|
69
69
|
await Promise.all(kpi.filter(el => el.sql).map(async (el) => {
|
@@ -73,61 +73,19 @@ export default async function reportData({
|
|
73
73
|
Object.assign(el, { count: rows?.[0]?.[fields[0].name] || 0, sql: user?.user_type === 'admin' ? el.sql : undefined });
|
74
74
|
}));
|
75
75
|
}
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
const { cls = {}, titles = {} } = (el.table ? el.meta : meta) || {};
|
83
|
-
const sql = el.sql || (el.table ? `select * from ${el.table} where ${el.query || 'true'}` : null) || q;
|
84
|
-
|
85
|
-
if (!el.agg) {
|
86
|
-
const { rows = [] } = await pg.query(sql).catch(err => {
|
87
|
-
Object.assign(el, { error: err.toString() });
|
88
|
-
}) || {};
|
89
|
-
await metaFormat({ rows, cls, sufix: false }, pg);
|
90
|
-
Object.assign(el, { rows, sql: user?.user_type === 'admin' ? sql : undefined });
|
91
|
-
} else {
|
92
|
-
const groupby = typeof el.groupby === 'string'
|
93
|
-
? { name: el.groupby }
|
94
|
-
: (el.groupby?.[0] || el.groupby);
|
95
|
-
|
96
|
-
const q1 = `select ${el.agg} ${groupby.name ? `${el.granularity ? `,date_trunc('${el.granularity}', ${groupby.name})` : `,${groupby.name}`}` : ''} as ${groupby.name} from (${sql}) t ${groupby.name ? `group by ${el.granularity ? `date_trunc('${el.granularity}', ${groupby.name})` : groupby.name}` : ''}`;
|
97
|
-
|
98
|
-
const { rows = [], fields = [] } = await pg.query(q1).catch(err => {
|
99
|
-
Object.assign(el, { error: err.toString() });
|
100
|
-
}) || {};
|
101
|
-
|
102
|
-
if (groupby.cls) {
|
103
|
-
Object.assign(cls, { [groupby.name]: groupby.cls });
|
104
|
-
}
|
105
|
-
|
106
|
-
await metaFormat({ rows, cls, sufix: false }, pg);
|
107
|
-
|
108
|
-
const types = el.table ? fields.reduce((acc, curr) => ({ ...acc, [curr.name]: pg.pgType?.[curr.dataTypeID] }), {}) : {};
|
109
|
-
|
110
|
-
const columns = el.table ? fields.map(el => ({
|
111
|
-
name: el.name,
|
112
|
-
title: titles?.[el.name] || el.name,
|
113
|
-
type: cls?.[el.name]
|
114
|
-
? 'Autocomplete'
|
115
|
-
: (
|
116
|
-
['date', 'timestamp with time zone', 'timestamp without time zone'].includes(types[el.name])
|
117
|
-
? 'Date'
|
118
|
-
: null
|
119
|
-
) || 'Text',
|
120
|
-
format: pg.pgType?.[el.dataTypeID],
|
121
|
-
data: cls?.[el.name],
|
122
|
-
})) : undefined;
|
123
|
-
|
124
|
-
Object.assign(el, { rows, columns, sql: user?.user_type === 'admin' ? q1 : undefined });
|
125
|
-
}
|
126
|
-
}));
|
127
|
-
}
|
76
|
+
|
77
|
+
widgets?.forEach?.((el) => Object.assign(el, {
|
78
|
+
agg: user?.user_type === 'admin' ? el.agg : undefined,
|
79
|
+
sql: user?.user_type === 'admin' ? el.sql : undefined
|
80
|
+
}));
|
128
81
|
|
129
82
|
const types = fields.reduce((acc, curr) => ({ ...acc, [curr.name]: pg.pgType?.[curr.dataTypeID] }), {});
|
130
83
|
|
84
|
+
const { rows = [] } = await pg.query(sql).catch(err => {
|
85
|
+
return reply.status(500).send('query error: ' + err.toString());
|
86
|
+
});
|
87
|
+
await metaFormat({ rows, cls: meta?.cls, sufix: false }, pg);
|
88
|
+
|
131
89
|
const columns = fields.map(el => ({
|
132
90
|
name: el.name,
|
133
91
|
title: meta?.titles?.[el.name] || el.name,
|
@@ -145,6 +103,9 @@ export default async function reportData({
|
|
145
103
|
return {
|
146
104
|
q: user?.user_type?.includes('admin') ? q : undefined,
|
147
105
|
kpi,
|
106
|
+
data: rows,
|
107
|
+
title,
|
108
|
+
subtitle,
|
148
109
|
widgets,
|
149
110
|
columns,
|
150
111
|
};
|
@@ -0,0 +1,90 @@
|
|
1
|
+
import path from 'node:path';
|
2
|
+
|
3
|
+
import { pgClients, getTemplate, metaFormat } from '@opengis/fastify-table/utils.js';
|
4
|
+
|
5
|
+
const maxLimit = 100;
|
6
|
+
|
7
|
+
export default async function widgetData({
|
8
|
+
pg = pgClients.client, params = {}, query = {}, user = {},
|
9
|
+
}, reply) {
|
10
|
+
if (!params?.name) {
|
11
|
+
return { message: 'not enough params: name', status: 400 };
|
12
|
+
}
|
13
|
+
|
14
|
+
if (!params?.widget) {
|
15
|
+
return reply.status(400).send('not enough params: widget');
|
16
|
+
}
|
17
|
+
|
18
|
+
const body = await getTemplate('report', params.name);
|
19
|
+
const loadTemplate = Array.isArray(body) ? body?.find?.(el => el[0].replace(path.extname(el[0]), '') === 'index')?.[1] : body;
|
20
|
+
|
21
|
+
if (!loadTemplate?.sql && !loadTemplate?.table) {
|
22
|
+
return reply.status(404).send(`report not found: ${params.name}`);
|
23
|
+
}
|
24
|
+
|
25
|
+
if (loadTemplate?.table && !pg.pk?.[loadTemplate.table]) {
|
26
|
+
return reply.status(404).send(`table not found: ${loadTemplate.table}`);
|
27
|
+
}
|
28
|
+
|
29
|
+
if (Array.isArray(body)) {
|
30
|
+
loadTemplate.widgets = [];
|
31
|
+
body.filter(el => el[0].replace(path.extname(el[0]), '') !== 'index').forEach((el) => {
|
32
|
+
loadTemplate.widgets.push(el[1]);
|
33
|
+
});
|
34
|
+
}
|
35
|
+
|
36
|
+
const { widgets = [] } = loadTemplate;
|
37
|
+
|
38
|
+
const widget = widgets.find(el => el.name === params.widget);
|
39
|
+
|
40
|
+
if (!widget) {
|
41
|
+
return reply.status(404).send(`widget not found: ${params.widget}`);
|
42
|
+
}
|
43
|
+
|
44
|
+
const { cls = {}, titles = {} } = widget.meta || {};
|
45
|
+
|
46
|
+
const offset = query.page && query.page > 0 ? (query.page - 1) * limit : 0;
|
47
|
+
const sql = widget.sql || `select * from ${widget.table} where ${widget.query || 'true'} limit ${maxLimit} offset ${offset}`;
|
48
|
+
|
49
|
+
const groupby = typeof widget.groupby === 'string'
|
50
|
+
? { name: widget.groupby }
|
51
|
+
: (widget.groupby?.[0] || widget.groupby);
|
52
|
+
|
53
|
+
if (groupby.cls) {
|
54
|
+
Object.assign(cls, { [groupby.name]: groupby.cls });
|
55
|
+
}
|
56
|
+
|
57
|
+
const q = widget.agg
|
58
|
+
? `select ${widget.agg} ${groupby.name ? `${widget.granularity ? `,date_trunc('${widget.granularity}', ${groupby.name})` : `,${groupby.name}`}` : ''} as ${groupby.name} from (${sql}) t ${groupby.name ? `group by ${widget.granularity ? `date_trunc('${widget.granularity}', ${groupby.name})` : groupby.name}` : ''}`
|
59
|
+
: sql;
|
60
|
+
|
61
|
+
const { rows = [], fields = [] } = await pg.query(q).catch(err => {
|
62
|
+
Object.assign(widget, { error: err.toString() });
|
63
|
+
}) || {};
|
64
|
+
await metaFormat({ rows, cls, sufix: false }, pg);
|
65
|
+
|
66
|
+
const types = fields.reduce((acc, curr) => ({ ...acc, [curr.name]: pg.pgType?.[curr.dataTypeID] }), {});
|
67
|
+
|
68
|
+
const columns = fields.map(el => ({
|
69
|
+
name: el.name,
|
70
|
+
title: titles?.[el.name] || el.name,
|
71
|
+
type: cls?.[el.name]
|
72
|
+
? 'Autocomplete'
|
73
|
+
: (
|
74
|
+
['date', 'timestamp with time zone', 'timestamp without time zone'].includes(types[el.name])
|
75
|
+
? 'Date'
|
76
|
+
: null
|
77
|
+
) || 'Text',
|
78
|
+
format: pg.pgType?.[el.dataTypeID],
|
79
|
+
data: cls?.[el.name],
|
80
|
+
}));
|
81
|
+
|
82
|
+
Object.assign(widget, {
|
83
|
+
source: rows,
|
84
|
+
columns,
|
85
|
+
agg: user?.user_type === 'admin' ? widget.agg : undefined,
|
86
|
+
sql: user?.user_type === 'admin' ? q : undefined,
|
87
|
+
});
|
88
|
+
|
89
|
+
return widget;
|
90
|
+
}
|
@@ -1,7 +1,9 @@
|
|
1
|
-
import
|
1
|
+
import tableData from './controllers/tableData.js';
|
2
|
+
import widgetData from './controllers/widgetData.js';
|
2
3
|
import reportList from './controllers/list.js';
|
3
4
|
|
4
5
|
export default async function route(app) {
|
5
6
|
app.get('/reports', {}, reportList);
|
6
|
-
app.get('/reports/:name', {},
|
7
|
+
app.get('/reports/:name', {}, tableData);
|
8
|
+
app.get('/reports/:name/:widget', {}, widgetData);
|
7
9
|
}
|