@opengis/bi 1.0.24 → 1.0.25

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.
Files changed (48) hide show
  1. package/dist/bi.js +1 -1
  2. package/dist/bi.umd.cjs +112 -138
  3. package/dist/{import-file-ChpPHgUN.js → import-file-D1BXgBLh.js} +10978 -11267
  4. package/dist/{map-component-mixin-C0Z88c8b.js → map-component-mixin-DVK92yIp.js} +254 -252
  5. package/dist/style.css +1 -1
  6. package/dist/vs-donut-DFofoWWE.js +148 -0
  7. package/dist/{vs-funnel-bar-Ba0HB6U8.js → vs-funnel-bar-CUEOqNnJ.js} +1 -1
  8. package/dist/{vs-map-T9bTjwSG.js → vs-map-DxaSAhZH.js} +3 -3
  9. package/dist/{vs-map-cluster-CQik8xir.js → vs-map-cluster-BqOHAVDj.js} +2 -2
  10. package/dist/{vs-number-DhACUDku.js → vs-number-C1s9pa7F.js} +1 -1
  11. package/dist/{vs-table-Df4lMM4d.js → vs-table-DCBSLb1s.js} +6 -6
  12. package/dist/{vs-text-D9iYudVA.js → vs-text-SoIN8Lt8.js} +1 -1
  13. package/package.json +4 -4
  14. package/server/routes/dashboard/controllers/dashboard.import.js +17 -5
  15. package/server/routes/dashboard/controllers/dashboard.js +39 -28
  16. package/server/routes/dashboard/controllers/dashboard.list.js +12 -9
  17. package/server/routes/data/controllers/data.js +13 -6
  18. package/server/routes/data/controllers/util/chartSQL.js +2 -1
  19. package/server/routes/data/controllers/util/normalizeData.js +7 -5
  20. package/server/routes/dataset/controllers/bi.dataset.list.js +1 -3
  21. package/server/routes/dataset/controllers/createDatasetPost.js +8 -5
  22. package/server/routes/dataset/controllers/dbTablePreview.js +3 -1
  23. package/server/routes/dataset/controllers/dbTables.js +3 -1
  24. package/server/routes/dataset/controllers/delete.js +1 -0
  25. package/server/routes/dataset/controllers/deleteDataset.js +1 -0
  26. package/server/routes/dataset/controllers/editDataset.js +1 -0
  27. package/server/routes/dataset/controllers/format.js +3 -1
  28. package/server/routes/dataset/controllers/insert.js +1 -0
  29. package/server/routes/dataset/controllers/update.js +1 -0
  30. package/server/routes/dataset/utils/createTableQuery.js +1 -1
  31. package/server/routes/dataset/utils/executeQuery.js +2 -2
  32. package/server/routes/edit/controllers/dashboard.add.js +16 -5
  33. package/server/routes/edit/controllers/dashboard.delete.js +11 -8
  34. package/server/routes/edit/controllers/dashboard.edit.js +20 -18
  35. package/server/routes/edit/controllers/widget.add.js +8 -8
  36. package/server/routes/edit/controllers/widget.del.js +4 -2
  37. package/server/routes/edit/controllers/widget.edit.js +25 -7
  38. package/server/routes/map/controllers/cluster.js +3 -2
  39. package/server/routes/map/controllers/clusterVtile.js +1 -1
  40. package/server/routes/map/controllers/geojson.js +2 -2
  41. package/server/routes/map/controllers/heatmap.js +2 -2
  42. package/server/routes/map/controllers/map.js +3 -2
  43. package/server/routes/map/controllers/vtile.js +1 -1
  44. package/server/templates/page/login.html +59 -0
  45. package/server/utils/getWidget.js +31 -18
  46. package/dist/vs-calendar-B4_gYR3Q.js +0 -116
  47. package/dist/vs-donut-BF1K_2LP.js +0 -150
  48. package/dist/vs-heatmap-Bzwa1rgF.js +0 -97
@@ -1,8 +1,10 @@
1
1
  function normalizeData(data, query = {}, columnTypes = []) {
2
+ const skip = [];
2
3
  ['x', 'groupby', 'granularity'].forEach((el) => {
3
4
  // console.log(el, query[el], columnTypes.find(col => col.name == query[el]))
4
5
  if (!columnTypes.find((col) => col.name == query[el])) {
5
- delete query[el];
6
+ if (query[el] && query[el] !== 'null') skip.push(`column not found: ${query[el]}`);
7
+ if (!(el === 'groupby' && query[el] === 'null')) delete query[el];
6
8
  }
7
9
  });
8
10
 
@@ -27,7 +29,7 @@ function normalizeData(data, query = {}, columnTypes = []) {
27
29
  ? `date_trunc('${granularity}',${xName})::date::text`
28
30
  : null) || xName;
29
31
 
30
- const metrics = Array.isArray(data.metrics) ? data.metrics : [data.metrics];
32
+ const metrics = Array.isArray(data.metrics || data.metric) ? (data.metrics || data.metric) : [data.metrics || data.metric];
31
33
  const metric =
32
34
  (query.metric ? `sum(${query.metric})` : null) ||
33
35
  (metrics.length
@@ -35,12 +37,12 @@ function normalizeData(data, query = {}, columnTypes = []) {
35
37
  ?.filter((el) => el && columnTypes.find((col) => col.name == (el?.name || el)))
36
38
  ?.map((el) => el.fx || `${el.operator || 'sum'}(${el.name || el})`)?.join(',') || 'count(*)')
37
39
  : 'count(*)');
38
-
40
+
39
41
  const yName = metrics?.[0]?.name || metrics?.[0];
40
42
  const yType = columnTypes.find((el) => el.name == yName)?.type;
41
43
 
42
44
  const { cls, table, filterCustom } = data;
43
- const groupby = query.groupby || data.groupby;
45
+ const groupby = (query.groupby || data.groupby) === 'null' ? null : (query.groupby || data.groupby);
44
46
  // const orderby = query.orderby || data.orderby || 'count(*)';
45
47
 
46
48
  const custom = query?.filterCustom
@@ -54,6 +56,6 @@ function normalizeData(data, query = {}, columnTypes = []) {
54
56
  ? `(select * from ${data?.table} t ${data.tableSQL.join(' \n ')} where ${where})q`
55
57
  : undefined;
56
58
 
57
- return { x, cls, metric, table, where, tableSQL, groupby, xName, xType, yName, yType };
59
+ return { x, cls, metric, table, where, tableSQL, groupby, xName, xType, yName, yType, error: skip.length ? skip.join(',') : undefined };
58
60
  }
59
61
  export default normalizeData;
@@ -17,9 +17,7 @@ const maxLimit = 100;
17
17
  * @returns {Object} rows Масив з колонками таблиці
18
18
  */
19
19
 
20
- const pg = pgClients.client;
21
-
22
- export default async function biDatasetList({ query = {} }) {
20
+ export default async function biDatasetList({ pg = pgClients.client, query = {} }) {
23
21
 
24
22
  const limit = Math.min(maxLimit, +(query.limit || 20));
25
23
  const offset = query.page && query.page > 0 ? (query.page - 1) * limit : 0;
@@ -32,6 +32,7 @@ export default async function createDatasetPost({
32
32
  table_name: existingTable,
33
33
  column_list: columns = [],
34
34
  dataset_url: datasetUrl,
35
+ encoding,
35
36
  } = body;
36
37
 
37
38
  const rootDir = getFolder(config, 'local');
@@ -56,7 +57,7 @@ export default async function createDatasetPost({
56
57
  return { message: 'Файл з вихідними даними не знайдено', status: 404 };
57
58
  }
58
59
 
59
- const json = await file2json({ filepath });
60
+ const json = await file2json({ filepath, encoding });
60
61
 
61
62
  // excel sheets fix?
62
63
  const data1 = (['.xls', '.xlsx'].includes(path.extname(filepath)) && !Array.isArray(json)) ? json[Object.keys(json)[0]] : json;
@@ -79,6 +80,7 @@ export default async function createDatasetPost({
79
80
  const { sql, pkey, table } = createTableQuery(fileColumns, name);
80
81
 
81
82
  const { datasetId, error } = await executeQuery({
83
+ pg,
82
84
  sql,
83
85
  data,
84
86
  name,
@@ -94,8 +96,8 @@ export default async function createDatasetPost({
94
96
 
95
97
  if (error) return { error, status: 500 };
96
98
 
97
- pgClients.client.pk[table] = pkey;
98
- pgClients.client.tlist.push(table);
99
+ pg.pk[table] = pkey;
100
+ pg.tlist.push(table);
99
101
  return { message: { id: datasetId, table, source: datasetUrl ? 'url' : 'file' }, status: 200 };
100
102
  }
101
103
 
@@ -114,6 +116,7 @@ export default async function createDatasetPost({
114
116
  const { sql, pkey, table } = createTableQuery(columns, name);
115
117
 
116
118
  const { datasetId, error } = await executeQuery({
119
+ pg,
117
120
  sql,
118
121
  name,
119
122
  table,
@@ -126,7 +129,7 @@ export default async function createDatasetPost({
126
129
 
127
130
  if (error) return { error, status: 500 };
128
131
 
129
- pgClients.client.pk[table] = pkey;
130
- pgClients.client.tlist.push(table);
132
+ pg.pk[table] = pkey;
133
+ pg.tlist.push(table);
131
134
  return { message: { id: datasetId, table, source: 'newtable' }, status: 200 };
132
135
  }
@@ -1,3 +1,5 @@
1
+ import { pgClients } from "@opengis/fastify-table/utils.js";
2
+
1
3
  const q = `select nspname||'.'||relname as table, json_agg(json_build_object('name',attname, 'type', a.atttypid::regtype, 'description', coalesce(col_description(attrelid, attnum),attname))) as columns
2
4
  from pg_attribute a
3
5
  left join pg_catalog.pg_attrdef d ON (a.attrelid, a.attnum) = (d.adrelid, d.adnum)
@@ -8,7 +10,7 @@ where a.attnum > 0 and nspname||'.'||relname = $1
8
10
  and not a.attisdropped
9
11
  group by nspname||'.'||relname limit 1`;
10
12
 
11
- export default async function dbTablePreview({ pg, params = {}, query = {} }) {
13
+ export default async function dbTablePreview({ pg = pgClients.client, params = {}, query = {} }) {
12
14
  if (!params?.name) {
13
15
  return { message: 'not enough params: name', status: 400 };
14
16
  }
@@ -1,4 +1,6 @@
1
- export default async function dbTables({ pg, query = {} }) {
1
+ import { pgClients } from "@opengis/fastify-table/utils.js";
2
+
3
+ export default async function dbTables({ pg = pgClients.client, query = {} }) {
2
4
  const q = `select
3
5
  t.table_schema ||'."'|| t.table_name ||'"' as table,
4
6
  obj_description(to_regclass(t.table_schema ||'."'|| t.table_name||'"')) as description,
@@ -30,6 +30,7 @@ export default async function datasetDataDelete({
30
30
  }
31
31
 
32
32
  const res = await dataDelete({
33
+ pg,
33
34
  id: tokenData?.id || params?.object_id,
34
35
  table,
35
36
  uid: user?.uid,
@@ -42,6 +42,7 @@ export default async function deleteDataset({
42
42
  }
43
43
 
44
44
  await dataDelete({
45
+ pg,
45
46
  table: 'bi.dataset',
46
47
  id: dataset.id,
47
48
  uid: user.uid,
@@ -70,6 +70,7 @@ export default async function editDataset(req) {
70
70
  }));
71
71
 
72
72
  await dataUpdate({
73
+ pg,
73
74
  table: 'bi.dataset',
74
75
  data: { column_list: columns },
75
76
  id: dataset.id,
@@ -1,7 +1,9 @@
1
+ import { pgClients } from "@opengis/fastify-table/utils.js";
2
+
1
3
  import getTableData from "../utils/getTableData.js";
2
4
  import getLayersData from "../utils/getLayersData.js";
3
5
 
4
- export default async function gisFormat({ query = {}, pg }) {
6
+ export default async function gisFormat({ query = {}, pg = pgClients.client }) {
5
7
  const time = [Date.now()];
6
8
  const { layer, table, id, lat, lng } = query;
7
9
 
@@ -33,6 +33,7 @@ export default async function datasetDataInsert({
33
33
  }
34
34
 
35
35
  const res = await dataInsert({
36
+ pg,
36
37
  table: add,
37
38
  data: body,
38
39
  uid: user?.uid,
@@ -32,6 +32,7 @@ export default async function datasetDataUpdate({
32
32
  }
33
33
 
34
34
  const res = await dataUpdate({
35
+ pg,
35
36
  id: tokenData?.id || params?.object_id,
36
37
  table,
37
38
  data: body,
@@ -36,7 +36,7 @@ export default function createTable(columns, name) {
36
36
  ?.join(';');
37
37
 
38
38
  const createQuery = `create table if not exists ${table} (
39
- ${pkey} text not null default public.uuid_generate_v4(),
39
+ ${pkey} text not null default encode(public.gen_random_bytes(6), 'hex'),
40
40
  geom public.geometry, ${columns ? `
41
41
  ${columns?.map?.((el) => `${el.name} ${el.type}`).join(', ')},` : ''}
42
42
  cdate timestamp without time zone not null default now(),
@@ -9,9 +9,9 @@ values($1,$2,$3,$4,$5,$6,$7) returning dataset_id`;
9
9
  const updateAppeal = 'update datasets_appeal.appeal set dataset_id=$1, data_key=$2 where ap_id=$3';
10
10
 
11
11
  export default async function executeQuery({
12
- sql, data, name, id, table, relPath, columns, pkey, source, user, url, dataKey,
12
+ pg = pgClients.client, sql, data, name, id, table, relPath, columns, pkey, source, user, url, dataKey,
13
13
  }) {
14
- const client = await pgClients.client.connect();
14
+ const client = await pg.connect();
15
15
  try {
16
16
  await client.query('BEGIN');
17
17
 
@@ -1,12 +1,23 @@
1
- import { pgClients, dataInsert } from "@opengis/fastify-table/utils.js";
1
+ import { pgClients, dataInsert, getPGAsync } from "@opengis/fastify-table/utils.js";
2
2
 
3
- const pg = pgClients.client;
4
-
5
- export default async function dashboardAdd(req) {
6
- const { body = {} } = req;
3
+ export default async function dashboardAdd(req, reply) {
4
+ const {
5
+ pg = pgClients.client,
6
+ body = {},
7
+ } = req;
7
8
  const time = Date.now();
8
9
 
10
+ if (body?.db) {
11
+ try {
12
+ const pg1 = await getPGAsync(body.db);
13
+ await pg1.query('select 1');
14
+ } catch (err) {
15
+ return reply.status(400).send('Некоректна база даних');
16
+ }
17
+ }
18
+
9
19
  const res = await dataInsert({
20
+ pg,
10
21
  table: 'bi.dashboard',
11
22
  data: body,
12
23
  }).then(el => el.rows?.[0] || {});
@@ -1,27 +1,25 @@
1
1
  import path from 'node:path';
2
2
  import { existsSync, readdirSync } from 'node:fs';
3
3
 
4
- import { pgClients } from '@opengis/fastify-table/utils.js';
5
-
6
- const pg = pgClients.client;
4
+ import { pgClients, dataDelete } from '@opengis/fastify-table/utils.js';
7
5
 
8
6
  const cwd = process.cwd();
9
7
  const dashboardDir = path.join(cwd, 'server/templates/dashboard');
10
8
 
11
- export default async function dashboardDelete({ params = {} }, reply) {
9
+ export default async function dashboardDelete({ pg = pgClients.client, params = {}, user }, reply) {
12
10
  if (!params?.id) {
13
11
  return reply.status(400).send('not enough params: id');
14
12
  }
15
13
 
16
- const dirContent = existsSync(dashboardDir)
17
- ? readdirSync(dashboardDir)
14
+ const dirContent = existsSync(dashboardDir)
15
+ ? readdirSync(dashboardDir)
18
16
  : [];
19
17
 
20
18
  if (dirContent.includes(params.id)) {
21
19
  return reply.status(403).send(`access restricted: ${params.id}`);
22
20
  }
23
21
 
24
- const { rowCount = 0 } = pg.pk?.['bi.dashboard']
22
+ const { rowCount = 0 } = pg.pk?.['bi.dashboard']
25
23
  ? await pg.query('select * from bi.dashboard where $1 in (dashboard_id,name)', [params.id])
26
24
  : {};
27
25
 
@@ -30,7 +28,12 @@ export default async function dashboardDelete({ params = {} }, reply) {
30
28
  }
31
29
 
32
30
  await pg.query(`delete from bi.widget where $1 in (dashboard_id)`, [params.id]);
33
- await pg.query(`delete from bi.dashboard where $1 in (dashboard_id,name)`, [params.id]);
31
+ await dataDelete({
32
+ pg,
33
+ table: 'bi.dashboard',
34
+ id: params.id,
35
+ uid: user?.uid,
36
+ });
34
37
 
35
38
  return reply.status(200).send('successfully deleted');
36
39
  }
@@ -1,35 +1,36 @@
1
- import { dataUpdate } from "@opengis/fastify-table/utils.js";
1
+ import { dataUpdate, pgClients, getPGAsync } from "@opengis/fastify-table/utils.js";
2
2
 
3
3
  export default async function dashboardEdit({
4
- pg, params = {}, body = {},
5
- }) {
4
+ pg = pgClients.client, params = {}, body = {},
5
+ }, reply) {
6
6
  const { name: dashboardName } = params;
7
7
  const { panels, widgets, table_name: tableName } = body;
8
8
 
9
- if (!dashboardName) {
10
- return {
11
- message: 'not enough params: dashboard name required',
12
- status: 400,
13
- };
9
+ if (body?.db) {
10
+ try {
11
+ const pg1 = await getPGAsync(body.db);
12
+ await pg1.query('select 1');
13
+ } catch (err) {
14
+ return reply.status(400).send('Некоректна база даних');
15
+ }
14
16
  }
15
17
 
16
- if (!tableName) {
17
- return {
18
- message: 'not enough params: table name required',
19
- status: 400,
20
- };
18
+ if (!dashboardName) {
19
+ return reply.status(400).send('not enough params: name');
21
20
  }
22
21
 
23
- const checkTable = await pg.query('select * from bi.dashboard where $1 in (table_name)', [tableName]);
24
-
25
- if (!checkTable.rows.length) {
26
- return { message: 'bad params', status: 401 };
22
+ if (!tableName) {
23
+ return reply.status(400).send('not enough params: table_name');
27
24
  }
28
25
 
29
26
  const row = await pg.query('select dashboard_id, widgets, panels from bi.dashboard where $1 in (dashboard_id, name)', [dashboardName])
30
27
  .then(el => el.rows?.[0] || {});
31
28
  const { dashboard_id: dashboardId } = row;
32
29
 
30
+ if (!dashboardId) {
31
+ return reply.status(400).send('dashboard not found');
32
+ }
33
+
33
34
  if (panels?.length && !widgets?.length) {
34
35
  row.widgets.forEach((el) => {
35
36
  const { title } = panels?.find?.(item => item.widget === el.name) || {};
@@ -42,13 +43,14 @@ export default async function dashboardEdit({
42
43
  }
43
44
 
44
45
  const res = await dataUpdate({
46
+ pg,
45
47
  table: 'bi.dashboard',
46
48
  id: dashboardId,
47
49
  data: body,
48
50
  });
49
51
 
50
52
  if (!Object.keys(res)?.length) {
51
- return { message: 'not found data', status: 404 };
53
+ return reply.status(404).send('not found data');
52
54
  }
53
55
 
54
56
  return {
@@ -1,5 +1,5 @@
1
1
  import { createHash } from 'node:crypto';
2
- import { dataInsert, dataUpdate } from "@opengis/fastify-table/utils.js";
2
+ import { dataInsert, dataUpdate, pgClients } from "@opengis/fastify-table/utils.js";
3
3
 
4
4
  /* eslint-disable import/extensions */
5
5
  import { yamlSafe } from '../../../../utils.js';
@@ -10,14 +10,14 @@ function generateUniqueName(prefix = 'bar') {
10
10
  return `${prefix}_${randomPart}_${timestamp}`;
11
11
  }
12
12
 
13
- export default async function widgetAdd({ pg, params = {}, body = {} }) {
13
+ export default async function widgetAdd({ pg = pgClients.client, params = {}, body = {} }) {
14
14
  const { name: dashboardName } = params;
15
15
  if (!dashboardName) {
16
16
  return { message: 'not enough params: id', status: 400 };
17
17
  }
18
18
  const data = body.yml ? yamlSafe.load(body.yml) : body;
19
19
 
20
- const row = await pg.query(`select dashboard_id, widgets, panels, table_name from bi.dashboard
20
+ const row = await pg.query(`select dashboard_id, widgets, panels, table_name, db from bi.dashboard
21
21
  where $1 in (dashboard_id,name)`, [dashboardName]).then(el => el.rows?.[0] || {});
22
22
 
23
23
  const tableName = data.data?.table
@@ -25,24 +25,23 @@ export default async function widgetAdd({ pg, params = {}, body = {} }) {
25
25
  || data.table_name
26
26
  || row.table_name;
27
27
 
28
- if (!tableName || !pg.pk?.[tableName]) {
28
+ if (!tableName || !(pg.pk?.[tableName] || pgClients[data.db || row.db || 'client']?.pk?.[tableName])) {
29
29
  return { message: 'bad params: table', status: 400 };
30
30
  }
31
31
 
32
32
  const { dashboard_id: dashboardId } = row;
33
33
 
34
+ const metric = data.data?.metrics || data.data?.metric || data?.metrics || data?.metric;
34
35
  Object.assign(data, {
35
36
  name: generateUniqueName(data.type),
36
37
  table_name: tableName,
37
- metrics:
38
- (data.data?.metrics || data?.metrics)?.[0] ||
39
- data.data?.metrics ||
40
- data?.metrics,
38
+ metrics: Array.isArray(metric) ? metric[0] : metric,
41
39
  });
42
40
 
43
41
  data.widget_id = createHash('md5').update([data?.name, dashboardId].join()).digest('hex').substr(0, 10);
44
42
 
45
43
  const res = await dataUpdate({
44
+ pg,
46
45
  table: 'bi.dashboard',
47
46
  id: dashboardId,
48
47
  data: {
@@ -57,6 +56,7 @@ export default async function widgetAdd({ pg, params = {}, body = {} }) {
57
56
  if (body?.yml) Object.assign(widgetData, { yml: body.yml });
58
57
 
59
58
  await dataInsert({
59
+ pg,
60
60
  table: 'bi.widget',
61
61
  data: widgetData,
62
62
  });
@@ -1,6 +1,6 @@
1
- import { dataDelete, dataUpdate } from '@opengis/fastify-table/utils.js';
1
+ import { dataDelete, dataUpdate, pgClients } from '@opengis/fastify-table/utils.js';
2
2
 
3
- export default async function widgetDel({ pg = {}, params = {} }) {
3
+ export default async function widgetDel({ pg = pgClients.client, params = {} }) {
4
4
  const { widget: widgetName, name: dashboardName } = params;
5
5
 
6
6
  if (!widgetName || !dashboardName) {
@@ -21,6 +21,7 @@ export default async function widgetDel({ pg = {}, params = {} }) {
21
21
  }
22
22
 
23
23
  await dataDelete({
24
+ pg,
24
25
  table: 'bi.widget',
25
26
  id: widgetId,
26
27
  });
@@ -43,6 +44,7 @@ export default async function widgetDel({ pg = {}, params = {} }) {
43
44
  : undefined;
44
45
 
45
46
  const res1 = await dataUpdate({
47
+ pg,
46
48
  table: 'bi.dashboard',
47
49
  id: dashboardId,
48
50
  data: body,
@@ -1,8 +1,8 @@
1
- import { dataUpdate } from '@opengis/fastify-table/utils.js';
1
+ import { dataUpdate, pgClients } from '@opengis/fastify-table/utils.js';
2
2
 
3
3
  import { getWidget, yamlSafe } from '../../../../utils.js';
4
4
 
5
- export default async function widgetEdit({ pg, body, params, }) {
5
+ export default async function widgetEdit({ pg = pgClients.client, body, params }) {
6
6
  const { widget: widgetName, name: dashboardName } = params;
7
7
  const data = body.yml && !body.style ? yamlSafe.load(body.yml) : body;
8
8
  const yml = body.yml ?? yamlSafe.dump(body.data);
@@ -21,19 +21,25 @@ export default async function widgetEdit({ pg, body, params, }) {
21
21
  [dashboardName, widgetName]).then(res1 => res1.rows?.[0] || {});
22
22
 
23
23
  // get Data
24
- const templateData = await getWidget({ dashboard: dashboardName, widget: widgetName });
24
+ const templateData = await getWidget({ pg, dashboard: dashboardName, widget: widgetName });
25
25
  if (!templateData) {
26
26
  return { message: `widget not found ${widgetName}`, status: 404 };
27
27
  }
28
28
 
29
+ if (data?.data) {
30
+ Object.assign(data, {
31
+ data: Object.keys(data.data || {})
32
+ ?.reduce?.((acc, curr) => ({ ...acc, [curr]: data.data[curr] === 'null' ? null : data.data[curr] }), {})
33
+ });
34
+ }
29
35
  const widgetData = ['style', 'data', 'type', 'title', 'controls']
30
36
  .filter(el => data[el])
31
37
  .reduce((p, el) => ({ ...p, [el]: data[el] }), {});
32
38
 
33
39
  //console.log(templateData)
34
40
  // get table
35
- const tableName = templateData.table || body.table || widgetData.data?.table;
36
- if (!tableName || !pg.pk?.[tableName]) {
41
+ const tableName = body.table || widgetData.data?.table_name || widgetData.data?.table || widgetData?.table_name || templateData.table;
42
+ if (!tableName || !(pg.pk?.[tableName] || pgClients[widgetData?.data?.db || templateData?.db || 'client']?.pk?.[tableName])) {
37
43
  return { message: 'bad params: table ' + tableName, status: 400 };
38
44
  }
39
45
 
@@ -41,15 +47,20 @@ export default async function widgetEdit({ pg, body, params, }) {
41
47
  Object.assign(widgetData, { yml })
42
48
  }
43
49
 
44
- Object.assign(widgetData, { table_name: tableName });
50
+ Object.assign(widgetData, { table_name: tableName, data: { ...widgetData?.data || {}, table_name: tableName } });
45
51
  console.log(widgetData);
46
52
  const rows = await dataUpdate({
53
+ pg,
47
54
  table: 'bi.widget',
48
55
  id: widgetId,
49
56
  data: widgetData,
50
57
  });
51
58
 
52
- const idx = widgets?.findIndex?.(el => el.name === widgetName) || -1;
59
+ const idx = widgets?.findIndex?.(el => el.name === widgetName)?.toString?.() || -1;
60
+ if (widgetData.hasOwnProperty('table_name') && idx > -1) {
61
+ widgets[idx].table_name = tableName;
62
+ widgets[idx].table = tableName;
63
+ }
53
64
  if (widgetData.hasOwnProperty('data') && idx > -1) {
54
65
  widgets[idx].data = widgetData.data
55
66
  }
@@ -59,8 +70,15 @@ export default async function widgetEdit({ pg, body, params, }) {
59
70
  if (widgetData.hasOwnProperty('style') && idx > -1) {
60
71
  widgets[idx].style = widgetData.style;
61
72
  }
73
+ if (widgetData.hasOwnProperty('type') && idx > -1) {
74
+ widgets[idx].type = widgetData.type;
75
+ }
76
+ if (widgetData.data?.type === 'text' && idx > -1) {
77
+ widgets[idx].data.text = widgetData.data?.text;
78
+ }
62
79
 
63
80
  await dataUpdate({
81
+ pg,
64
82
  table: 'bi.dashboard',
65
83
  id: dashboardId,
66
84
  data: { widgets },
@@ -6,14 +6,15 @@ import downloadClusterData from './utils/downloadClusterData.js';
6
6
 
7
7
  const clusterExists = {};
8
8
 
9
- export default async function cluster({ query = {} }) {
9
+ export default async function cluster(req) {
10
+ const { query = {} } = req;
10
11
  const { widget, filter, dashboard, search } = query;
11
12
 
12
13
  if (!widget) {
13
14
  return { message: 'not enough params: widget', status: 400 };
14
15
  }
15
16
 
16
- const { pg = pgClients.client, data } = await getWidget({ dashboard, widget });
17
+ const { pg = req.pg || pgClients.client, data } = await getWidget({ pg: req.pg, dashboard, widget });
17
18
 
18
19
  const pkey = pg.pk?.[data?.table];
19
20
 
@@ -30,7 +30,7 @@ export default async function clusterVtile(req, reply) {
30
30
  return { message: 'not enough params: widget', status: 400 };
31
31
  }
32
32
 
33
- const { pg = pgClients.client, data } = await getWidget({ dashboard, widget });
33
+ const { pg = req.pg || pgClients.client, data } = await getWidget({ pg: req.pg, dashboard, widget });
34
34
 
35
35
  const headers = {
36
36
  'Content-Type': 'application/x-protobuf',
@@ -35,10 +35,10 @@ export default async function geojson(req, reply) {
35
35
  return { message: 'not enough params: widget', status: 400 };
36
36
  }
37
37
 
38
- const data = await getWidget({ dashboard, widget });
38
+ const data = await getWidget({ pg: req.pg, dashboard, widget });
39
39
  if (data.status) return data;
40
40
 
41
- const pg = data.pg || pgClients.client;
41
+ const pg = data.pg || req.pg || pgClients.client;
42
42
  const hash = [pointZoom, filter].filter((el) => el).join();
43
43
 
44
44
  const root = getFolder(req);
@@ -23,7 +23,7 @@ export default async function heatmap(req, reply) {
23
23
  return { message: 'not enough params: dashboard / widget', status: 400 };
24
24
  }
25
25
 
26
- const { data } = await getWidget({ widget, dashboard });
26
+ const { data } = await getWidget({ pg: req.pg, widget, dashboard });
27
27
 
28
28
  if (!data?.table) {
29
29
  return { message: 'widget not found: ' + widget, status: 400 };
@@ -48,7 +48,7 @@ export default async function heatmap(req, reply) {
48
48
  }
49
49
  }
50
50
 
51
- const pg = data.pg || pgClients.client;
51
+ const pg = data.pg || req.pg || pgClients.client;
52
52
 
53
53
  if (!pg.pk?.[data.table]) {
54
54
  return { message: `table not found: ${data.table}`, status: 404 };
@@ -2,10 +2,11 @@ import { pgClients, getFilterSQL } from '@opengis/fastify-table/utils.js';
2
2
 
3
3
  import { getWidget } from '../../../../utils.js';
4
4
 
5
- export default async function map({ query = {} }) {
5
+ export default async function map(req) {
6
+ const { query = {} } = req;
6
7
  const { dashboard, widget } = query;
7
8
 
8
- const { pg = pgClients.client, data, type, layers } = await getWidget({ dashboard, widget });
9
+ const { pg = req.pg || pgClients.client, data, type, layers } = await getWidget({ pg: req.pg, dashboard, widget });
9
10
 
10
11
  if (!['map'].includes(type)) {
11
12
  return { message: 'access restricted: invalid widget type', status: 403 };
@@ -59,7 +59,7 @@ export default async function vtile(req, reply) {
59
59
  return { message: 'not enough params: xyz', status: 400 };
60
60
  }
61
61
 
62
- const { pg = pgClients.client, data } = await getWidget({ widget, dashboard });
62
+ const { pg = req.pg || pgClients.client, data } = await getWidget({ pg: req.pg, widget, dashboard });
63
63
 
64
64
  const headers = {
65
65
  'Content-Type': 'application/x-protobuf',