@opengis/admin 0.3.101 → 0.3.103

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengis/admin",
3
- "version": "0.3.101",
3
+ "version": "0.3.103",
4
4
  "description": "This project Softpro Admin",
5
5
  "main": "dist/admin.js",
6
6
  "type": "module",
@@ -6,7 +6,7 @@ import getFilterQuery from '../utils/getFilterQuery.js';
6
6
 
7
7
  const maxLimit = 100;
8
8
 
9
- export default async function reportData({
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 "${el.name}"`)?.join?.(',') : '';
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
- if (widgets?.length) {
77
- await Promise.all(widgets.map(async (el) => {
78
- if (el.table && !pg.pk?.[el.table]) {
79
- return { error: `table not found: ${el.table}` };
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} as metric ${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 reportData from './controllers/data.js';
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', {}, reportData);
7
+ app.get('/reports/:name', {}, tableData);
8
+ app.get('/reports/:name/:widget', {}, widgetData);
7
9
  }