@opengis/admin 0.1.56 → 0.1.57
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +29 -29
- package/config.js +4 -4
- package/dist/{add-page-B8kJBazL.js → add-page-ChIfqEIA.js} +1 -1
- package/dist/{admin-interface-DWshL-SZ.js → admin-interface-DjKoGiLz.js} +3 -3
- package/dist/{admin-view-DdkTlobT.js → admin-view-CoSA8JYC.js} +2 -2
- package/dist/admin.js +1 -1
- package/dist/admin.umd.cjs +40 -40
- package/dist/{card-page-Cqy3g7da.js → card-page-mrDH9Sn9.js} +2 -2
- package/dist/{card-view-BO_4pVnc.js → card-view-g2LiFVJC.js} +1 -1
- package/dist/{edit-page-CO36ZCNA.js → edit-page-CnDwsZCs.js} +1 -1
- package/dist/{import-file-qXjEXyOF.js → import-file-BRMqCIEX.js} +20 -13
- package/dist/style.css +1 -1
- package/module/settings/card/admin.roles.table/access.hbs +27 -27
- package/module/settings/card/admin.roles.table/general_info.hbs +16 -16
- package/module/settings/card/admin.roles.table/index.yml +14 -14
- package/module/settings/card/admin.roles.table/users.hbs +27 -27
- package/module/settings/card/admin.routes.table/general_info.hbs +40 -40
- package/module/settings/card/admin.routes.table/index.yml +8 -8
- package/module/settings/card/admin.routes.table/users.hbs +33 -33
- package/module/settings/card/admin.users.table/general_info.hbs +25 -25
- package/module/settings/card/admin.users.table/index.yml +12 -12
- package/module/settings/card/admin.users.table/logs.hbs +30 -30
- package/module/settings/card/admin.users.table/user_roles.hbs +24 -24
- package/module/settings/cls/core.actions.json +13 -13
- package/module/settings/cls/core.scope.json +13 -13
- package/module/settings/cls/properties.site_status.json +13 -13
- package/module/settings/cls/properties.widget_status.json +13 -13
- package/module/settings/cls/users.user_type.json +13 -13
- package/module/settings/form/admin.access.form.json +36 -36
- package/module/settings/form/admin.custom_column.form.json +71 -71
- package/module/settings/form/admin.properties.form.json +15 -15
- package/module/settings/form/admin.roles.form.json +19 -19
- package/module/settings/form/admin.routes.form.json +25 -25
- package/module/settings/form/admin.user_properties.form.json +15 -15
- package/module/settings/form/admin.user_roles.form.json +21 -21
- package/module/settings/form/admin.users.form.json +150 -150
- package/module/settings/form/user.user_roles.form.json +13 -13
- package/module/settings/interface/admin.properties.json +4 -4
- package/module/settings/interface/admin.roles.json +4 -4
- package/module/settings/interface/admin.routes.json +4 -4
- package/module/settings/interface/admin.users.json +4 -4
- package/module/settings/menu.json +50 -50
- package/module/settings/select/core.roles.json +2 -2
- package/module/settings/select/core.routes.sql +1 -1
- package/module/settings/select/core.user_uid.sql +1 -1
- package/module/settings/table/admin.access.table.json +77 -77
- package/module/settings/table/admin.custom_column.table.json +94 -94
- package/module/settings/table/admin.properties.table.json +33 -33
- package/module/settings/table/admin.roles.table.json +58 -58
- package/module/settings/table/admin.routes.table.json +67 -67
- package/module/settings/table/admin.user_properties.table.json +28 -28
- package/module/settings/table/admin.user_roles.table.json +66 -66
- package/module/settings/table/admin.users.table.json +119 -119
- package/package.json +81 -81
- package/plugin.js +162 -162
- package/server/helpers/controllers/badge.js +11 -11
- package/server/helpers/controllers/hb.js +2 -2
- package/server/helpers/controllers/map.js +2 -2
- package/server/helpers/controllers/mls.js +2 -2
- package/server/helpers/controllers/vue.js +2 -2
- package/server/helpers/index.mjs +13 -13
- package/server/plugins/docs.js +28 -28
- package/server/plugins/hook.js +228 -229
- package/server/plugins/vite.js +69 -69
- package/server/routes/calendar/controllers/calendar.data.js +88 -88
- package/server/routes/calendar/index.mjs +17 -17
- package/server/routes/data/controllers/cardData.js +56 -56
- package/server/routes/data/controllers/cardTabData.js +49 -49
- package/server/routes/data/controllers/funcs/getFilterSQL/index.js +92 -92
- package/server/routes/data/controllers/funcs/getFilterSQL/util/formatValue.js +170 -170
- package/server/routes/data/controllers/funcs/getFilterSQL/util/getCustomQuery.js +13 -13
- package/server/routes/data/controllers/funcs/getFilterSQL/util/getFilterQuery.js +64 -64
- package/server/routes/data/controllers/funcs/getFilterSQL/util/getOptimizedQuery.js +12 -12
- package/server/routes/data/controllers/funcs/getFilterSQL/util/getTableSql.js +34 -34
- package/server/routes/data/controllers/tableData.js +145 -145
- package/server/routes/data/controllers/tableDataId.js +27 -27
- package/server/routes/data/controllers/tableFilter.js +63 -63
- package/server/routes/data/controllers/utils/assignTokens.js +30 -30
- package/server/routes/data/controllers/utils/getColumns.js +21 -21
- package/server/routes/data/index.mjs +15 -15
- package/server/routes/data/schema.js +7 -7
- package/server/routes/menu/controllers/getMenu.js +34 -34
- package/server/routes/menu/index.mjs +5 -5
- package/server/routes/notifications/controllers/readNotifications.js +30 -30
- package/server/routes/notifications/controllers/userNotifications.js +64 -64
- package/server/routes/notifications/hook/onWidgetSet.js +63 -63
- package/server/routes/notifications/index.mjs +40 -40
- package/server/routes/properties/controllers/admin.properties.get.js +29 -29
- package/server/routes/properties/controllers/user.properties.get.js +34 -34
- package/server/routes/properties/controllers/user.properties.post.js +30 -30
- package/server/routes/properties/funcs/getSettings.js +56 -56
- package/server/routes/properties/funcs/setSettings.js +44 -44
- package/server/routes/properties/funcs/utils/dataInsert.js +26 -26
- package/server/routes/properties/index.mjs +26 -26
- package/server/routes/root.mjs +3 -3
- package/server/routes/templates/controllers/getTemplate.js +16 -16
- package/server/routes/templates/index.mjs +14 -14
- package/server/templates/cls/itree.recrzone_category.json +73 -73
- package/server/templates/cls/test.json +9 -9
- package/server/templates/form/admin.user_cls.data.form.json +49 -49
- package/server/templates/form/admin.user_group_rel.form.json +21 -21
- package/server/templates/form/cp_building.form.json +32 -32
- package/server/templates/form/form-user-pass.json +10 -10
- package/server/templates/form/form-user_group.json +39 -39
- package/server/templates/form/form-users.json +156 -156
- package/server/templates/form/user_group_access.form.json +22 -22
- package/server/templates/select/account_id.json +2 -2
- package/server/templates/table/gis.dataset.table.json +43 -43
- package/server/templates/table/management.user_group.table.json +112 -112
- package/server/templates/table/management.users.table.json +126 -126
- package/utils.js +21 -21
@@ -1,146 +1,146 @@
|
|
1
|
-
import {
|
2
|
-
getMeta, getAccess, getTemplate, metaFormat, getSelectVal, gisIRColumn,
|
3
|
-
} from "@opengis/fastify-table/utils.js";
|
4
|
-
|
5
|
-
import getFilterSQL from "./funcs/getFilterSQL/index.js";
|
6
|
-
|
7
|
-
import assignTokens from './utils/assignTokens.js';
|
8
|
-
|
9
|
-
import getColumns from './utils/getColumns.js';
|
10
|
-
|
11
|
-
const maxLimit = 100;
|
12
|
-
|
13
|
-
export default async function getTableData(req) {
|
14
|
-
const time = Date.now();
|
15
|
-
|
16
|
-
const {
|
17
|
-
pg, params, funcs = {}, query = {}, opt = {}, session = {}, mode = 'table',
|
18
|
-
} = req;
|
19
|
-
const { uid } = session.passport?.user || {};
|
20
|
-
|
21
|
-
try {
|
22
|
-
const loadTable = await getTemplate('table', params.table);
|
23
|
-
|
24
|
-
if (!loadTable) {
|
25
|
-
return { message: 'template not found', status: 404 };
|
26
|
-
}
|
27
|
-
|
28
|
-
const {
|
29
|
-
table, sql, form, meta, sqlColumns, ispublic,
|
30
|
-
} = loadTable;
|
31
|
-
const columns = loadTable.columns || loadTable.colModel;
|
32
|
-
|
33
|
-
const { pk, columns: dbColumns = [] } = await getMeta(table);
|
34
|
-
|
35
|
-
if (!pk) {
|
36
|
-
return { message: `table not found: ${table}`, status: 404 };
|
37
|
-
}
|
38
|
-
|
39
|
-
const { cols, columnList, extraKeys, schema } = await getColumns({
|
40
|
-
pg, columns, params, opt, loadTable, form, table, dbColumns, mode, uid,
|
41
|
-
});
|
42
|
-
|
43
|
-
const metaCols = Object.keys(loadTable?.meta?.cls || {}).filter((el) => !cols.includes(el)).length
|
44
|
-
? `,${Object.keys(loadTable?.meta?.cls || {})?.filter((el) => !cols.includes(el)).join(',')}`
|
45
|
-
: '';
|
46
|
-
|
47
|
-
const sqlTable = sql?.filter?.((el) => !el?.disabled && el?.sql?.replace).map((el, i) => ` left join lateral (${el.sql.replace('{{uid}}', uid)}) ${el.name || `t${i}`} on 1=1 `)?.join('') || '';
|
48
|
-
|
49
|
-
if (params.id && columnList.includes(params.id)) {
|
50
|
-
return gisIRColumn({
|
51
|
-
pg, funcs, layer: params.table, column: params.id, sql: query.sql,
|
52
|
-
});
|
53
|
-
}
|
54
|
-
|
55
|
-
const fData = query.filter || query.search ? await getFilterSQL({
|
56
|
-
funcs,
|
57
|
-
filter: query.filter,
|
58
|
-
search: query.search,
|
59
|
-
table: params.table,
|
60
|
-
uid,
|
61
|
-
json: 1,
|
62
|
-
}) : {};
|
63
|
-
|
64
|
-
const keyQuery = query.key && loadTable.key && !(opt?.id || params.id) ? `${loadTable.key}=$1` : null;
|
65
|
-
|
66
|
-
const limit = Math.min(maxLimit, +(query.limit || 20));
|
67
|
-
|
68
|
-
const offset = query.page && query.page > 0 ? ` offset ${(query.page - 1) * limit}` : '';
|
69
|
-
// id, query, filter
|
70
|
-
const [orderColumn, orderDir] = (query.order || loadTable.order || '').split(/[- ]/);
|
71
|
-
|
72
|
-
const order = columnList.includes(orderColumn) && orderColumn?.length ? `order by ${orderColumn} ${query.desc || orderDir === 'desc' ? 'desc' : ''}` : '';
|
73
|
-
|
74
|
-
const state = loadTable.filterState && query.state ? loadTable.filterState?.find((el) => el.name === query.state)?.sql : null;
|
75
|
-
|
76
|
-
const custom = loadTable.filterCustom && query.custom ? loadTable.filterCustom?.find((el) => el.name === query.custom)?.sql : null;
|
77
|
-
|
78
|
-
const search = loadTable.meta?.search && query.search ? `(${loadTable.meta?.search.split(',').map(el => `${el} ilike '%${query.search}%'`).join(' or ')})` : null;
|
79
|
-
|
80
|
-
const queryBbox = query?.bbox ? query.bbox.replace(/ /g, ',').split(',')?.map((el) => el - 0) : [];
|
81
|
-
|
82
|
-
const queryPolyline = meta?.bbox && query?.polyline ? `ST_Contains(ST_MakePolygon(ST_LineFromEncodedPolyline('${query?.polyline}')),${meta.bbox})` : undefined;
|
83
|
-
|
84
|
-
const bbox = meta?.bbox && queryBbox.filter((el) => !Number.isNaN(el))?.length === 4 ? `${meta.bbox} && 'box(${queryBbox[0]} ${queryBbox[1]},${queryBbox[2]} ${queryBbox[3]})'::box2d ` : undefined;
|
85
|
-
|
86
|
-
const access = await getAccess(req, params.table);
|
87
|
-
|
88
|
-
const where = [(opt?.id || params.id ? ` "${pk}" = $1` : null), keyQuery, loadTable.query, fData.q, state, custom, search, access?.query || '1=1', bbox, queryPolyline, fData.extraQuery].filter((el) => el);
|
89
|
-
|
90
|
-
const q = `select ${pk ? `"${pk}" as id,` : ''} ${columnList.includes('geom') ? 'st_asgeojson(geom)::json as geom,' : ''} ${query.id || query.key ? '*' : sqlColumns || cols || '*'} ${metaCols} from ${table} t ${sqlTable} where ${where.join(' and ') || 'true'} ${order} ${offset} limit ${limit}`;
|
91
|
-
|
92
|
-
if (query.sql === '1') { return { message: q }; }
|
93
|
-
|
94
|
-
const { rows } = await pg.query(q, (opt?.id || params.id ? [opt?.id || params.id] : null) || (query.key && loadTable.key ? [query.key] : []));
|
95
|
-
|
96
|
-
const total = keyQuery || opt?.id || params.id ? rows.length : await pg.queryCache(`select count(*) from ${table} t ${sqlTable} where ${where.join(' and ') || 'true'}`).then((el) => (el?.rows[0]?.count || 0) - 0);
|
97
|
-
|
98
|
-
// form DataTable
|
99
|
-
if (extraKeys?.length && mode === 'card') {
|
100
|
-
await Promise.all(rows?.map(async (row) => {
|
101
|
-
await Promise.all(extraKeys?.map(async (key) => {
|
102
|
-
const { colModel, table: extraTable, parent_id: parentId } = schema[key];
|
103
|
-
const { rows: extraRows } = await pg.query(`select ${parentId} as parent, ${colModel.map((col) => col.name).join(',')} from ${extraTable} a where ${parentId}=$1`, [row.id]);
|
104
|
-
Object.assign(row, { [key]: extraRows });
|
105
|
-
}));
|
106
|
-
}));
|
107
|
-
}
|
108
|
-
|
109
|
-
// admin.custom_column - user column data
|
110
|
-
const { rows: properties = [] } = await pg.query(`select column_id, name, title, format, data from admin.custom_column
|
111
|
-
where _table and entity=$1 and uid=$2`, [params.table, uid]);
|
112
|
-
const extraColumnList = properties.map((row) => ({ id: row.column_id, name: row.name, title: row.title, format: row.format, data: row.data }));
|
113
|
-
extraColumnList.forEach((col) => columns.push(col));
|
114
|
-
const { rows: extraData = [] } = await pg.query(`select object_id, json_object_agg( property_id, coalesce(value_date::text,value_text) ) as extra from crm.extra_data
|
115
|
-
where property_entity=$1 and property_id=any($2) and object_id=any($3) group by object_id`, [params.table, extraColumnList?.map((el) => el.id), rows.map((el) => el.id)]);
|
116
|
-
rows.filter((row) => extraData.map((el) => el?.object_id).includes(row.id)).forEach((row) => {
|
117
|
-
const { extra = {} } = extraData.find((el) => el.object_id === row.id);
|
118
|
-
Object.assign(row, { ...Object.fromEntries(Object.entries(extra).map((el) => [extraColumnList.find((col) => col.id === el[0]).name, el[1]])) });
|
119
|
-
});
|
120
|
-
|
121
|
-
// admin.custom_column - metaFormat
|
122
|
-
await Promise.all(extraColumnList.filter((el) => el?.data).map(async (attr) => {
|
123
|
-
const values = [...new Set(rows?.map((el) => el[attr.name]).flat())].filter((el) => el);
|
124
|
-
if (!values.length) return;
|
125
|
-
const cls = await getSelectVal({ name: attr.data, values });
|
126
|
-
if (!cls) return;
|
127
|
-
rows.forEach(el => {
|
128
|
-
const val = el[attr.name]?.map?.(c => cls[c] || c) || cls[el[attr.name]] || el[attr.name];
|
129
|
-
if (!val) return;
|
130
|
-
Object.assign(el, { [val?.color ? `${attr.name}_data` : `${attr.name}_text`]: (val.color ? val : val.text || val) });
|
131
|
-
});
|
132
|
-
}));
|
133
|
-
|
134
|
-
await metaFormat({ funcs, rows, table: params.table });
|
135
|
-
|
136
|
-
const res = {
|
137
|
-
time: Date.now() - time, card: loadTable.card, actions: loadTable.actions, access, total, count: rows.length, pk, form, meta, columns,
|
138
|
-
};
|
139
|
-
const addToken = assignTokens({ rows, funcs, ispublic, uid: 1, loadTable });
|
140
|
-
Object.assign(res, { rows, addToken });
|
141
|
-
|
142
|
-
return res;
|
143
|
-
} catch (err) {
|
144
|
-
return { message: err.toString(), status: 500 };
|
145
|
-
}
|
1
|
+
import {
|
2
|
+
getMeta, getAccess, getTemplate, metaFormat, getSelectVal, gisIRColumn,
|
3
|
+
} from "@opengis/fastify-table/utils.js";
|
4
|
+
|
5
|
+
import getFilterSQL from "./funcs/getFilterSQL/index.js";
|
6
|
+
|
7
|
+
import assignTokens from './utils/assignTokens.js';
|
8
|
+
|
9
|
+
import getColumns from './utils/getColumns.js';
|
10
|
+
|
11
|
+
const maxLimit = 100;
|
12
|
+
|
13
|
+
export default async function getTableData(req) {
|
14
|
+
const time = Date.now();
|
15
|
+
|
16
|
+
const {
|
17
|
+
pg, params, funcs = {}, query = {}, opt = {}, session = {}, mode = 'table',
|
18
|
+
} = req;
|
19
|
+
const { uid } = session.passport?.user || {};
|
20
|
+
|
21
|
+
try {
|
22
|
+
const loadTable = await getTemplate('table', params.table);
|
23
|
+
|
24
|
+
if (!loadTable) {
|
25
|
+
return { message: 'template not found', status: 404 };
|
26
|
+
}
|
27
|
+
|
28
|
+
const {
|
29
|
+
table, sql, form, meta, sqlColumns, ispublic,
|
30
|
+
} = loadTable;
|
31
|
+
const columns = loadTable.columns || loadTable.colModel;
|
32
|
+
|
33
|
+
const { pk, columns: dbColumns = [] } = await getMeta(table);
|
34
|
+
|
35
|
+
if (!pk) {
|
36
|
+
return { message: `table not found: ${table}`, status: 404 };
|
37
|
+
}
|
38
|
+
|
39
|
+
const { cols, columnList, extraKeys, schema } = await getColumns({
|
40
|
+
pg, columns, params, opt, loadTable, form, table, dbColumns, mode, uid,
|
41
|
+
});
|
42
|
+
|
43
|
+
const metaCols = Object.keys(loadTable?.meta?.cls || {}).filter((el) => !cols.includes(el)).length
|
44
|
+
? `,${Object.keys(loadTable?.meta?.cls || {})?.filter((el) => !cols.includes(el)).join(',')}`
|
45
|
+
: '';
|
46
|
+
|
47
|
+
const sqlTable = sql?.filter?.((el) => !el?.disabled && el?.sql?.replace).map((el, i) => ` left join lateral (${el.sql.replace('{{uid}}', uid)}) ${el.name || `t${i}`} on 1=1 `)?.join('') || '';
|
48
|
+
|
49
|
+
if (params.id && columnList.includes(params.id)) {
|
50
|
+
return gisIRColumn({
|
51
|
+
pg, funcs, layer: params.table, column: params.id, sql: query.sql,
|
52
|
+
});
|
53
|
+
}
|
54
|
+
|
55
|
+
const fData = query.filter || query.search ? await getFilterSQL({
|
56
|
+
funcs,
|
57
|
+
filter: query.filter,
|
58
|
+
search: query.search,
|
59
|
+
table: params.table,
|
60
|
+
uid,
|
61
|
+
json: 1,
|
62
|
+
}) : {};
|
63
|
+
|
64
|
+
const keyQuery = query.key && loadTable.key && !(opt?.id || params.id) ? `${loadTable.key}=$1` : null;
|
65
|
+
|
66
|
+
const limit = Math.min(maxLimit, +(query.limit || 20));
|
67
|
+
|
68
|
+
const offset = query.page && query.page > 0 ? ` offset ${(query.page - 1) * limit}` : '';
|
69
|
+
// id, query, filter
|
70
|
+
const [orderColumn, orderDir] = (query.order || loadTable.order || '').split(/[- ]/);
|
71
|
+
|
72
|
+
const order = columnList.includes(orderColumn) && orderColumn?.length ? `order by ${orderColumn} ${query.desc || orderDir === 'desc' ? 'desc' : ''}` : '';
|
73
|
+
|
74
|
+
const state = loadTable.filterState && query.state ? loadTable.filterState?.find((el) => el.name === query.state)?.sql : null;
|
75
|
+
|
76
|
+
const custom = loadTable.filterCustom && query.custom ? loadTable.filterCustom?.find((el) => el.name === query.custom)?.sql : null;
|
77
|
+
|
78
|
+
const search = loadTable.meta?.search && query.search ? `(${loadTable.meta?.search.split(',').map(el => `${el} ilike '%${query.search}%'`).join(' or ')})` : null;
|
79
|
+
|
80
|
+
const queryBbox = query?.bbox ? query.bbox.replace(/ /g, ',').split(',')?.map((el) => el - 0) : [];
|
81
|
+
|
82
|
+
const queryPolyline = meta?.bbox && query?.polyline ? `ST_Contains(ST_MakePolygon(ST_LineFromEncodedPolyline('${query?.polyline}')),${meta.bbox})` : undefined;
|
83
|
+
|
84
|
+
const bbox = meta?.bbox && queryBbox.filter((el) => !Number.isNaN(el))?.length === 4 ? `${meta.bbox} && 'box(${queryBbox[0]} ${queryBbox[1]},${queryBbox[2]} ${queryBbox[3]})'::box2d ` : undefined;
|
85
|
+
|
86
|
+
const access = await getAccess(req, params.table);
|
87
|
+
|
88
|
+
const where = [(opt?.id || params.id ? ` "${pk}" = $1` : null), keyQuery, loadTable.query, fData.q, state, custom, search, access?.query || '1=1', bbox, queryPolyline, fData.extraQuery].filter((el) => el);
|
89
|
+
|
90
|
+
const q = `select ${pk ? `"${pk}" as id,` : ''} ${columnList.includes('geom') ? 'st_asgeojson(geom)::json as geom,' : ''} ${query.id || query.key ? '*' : sqlColumns || cols || '*'} ${metaCols} from ${table} t ${sqlTable} where ${where.join(' and ') || 'true'} ${order} ${offset} limit ${limit}`;
|
91
|
+
|
92
|
+
if (query.sql === '1') { return { message: q }; }
|
93
|
+
|
94
|
+
const { rows } = await pg.query(q, (opt?.id || params.id ? [opt?.id || params.id] : null) || (query.key && loadTable.key ? [query.key] : []));
|
95
|
+
|
96
|
+
const total = keyQuery || opt?.id || params.id ? rows.length : await pg.queryCache(`select count(*) from ${table} t ${sqlTable} where ${where.join(' and ') || 'true'}`).then((el) => (el?.rows[0]?.count || 0) - 0);
|
97
|
+
|
98
|
+
// form DataTable
|
99
|
+
if (extraKeys?.length && mode === 'card') {
|
100
|
+
await Promise.all(rows?.map(async (row) => {
|
101
|
+
await Promise.all(extraKeys?.map(async (key) => {
|
102
|
+
const { colModel, table: extraTable, parent_id: parentId } = schema[key];
|
103
|
+
const { rows: extraRows } = await pg.query(`select ${parentId} as parent, ${colModel.map((col) => col.name).join(',')} from ${extraTable} a where ${parentId}=$1`, [row.id]);
|
104
|
+
Object.assign(row, { [key]: extraRows });
|
105
|
+
}));
|
106
|
+
}));
|
107
|
+
}
|
108
|
+
|
109
|
+
// admin.custom_column - user column data
|
110
|
+
const { rows: properties = [] } = await pg.query(`select column_id, name, title, format, data from admin.custom_column
|
111
|
+
where _table and entity=$1 and uid=$2`, [params.table, uid]);
|
112
|
+
const extraColumnList = properties.map((row) => ({ id: row.column_id, name: row.name, title: row.title, format: row.format, data: row.data }));
|
113
|
+
extraColumnList.forEach((col) => columns.push(col));
|
114
|
+
const { rows: extraData = [] } = await pg.query(`select object_id, json_object_agg( property_id, coalesce(value_date::text,value_text) ) as extra from crm.extra_data
|
115
|
+
where property_entity=$1 and property_id=any($2) and object_id=any($3) group by object_id`, [params.table, extraColumnList?.map((el) => el.id), rows.map((el) => el.id)]);
|
116
|
+
rows.filter((row) => extraData.map((el) => el?.object_id).includes(row.id)).forEach((row) => {
|
117
|
+
const { extra = {} } = extraData.find((el) => el.object_id === row.id);
|
118
|
+
Object.assign(row, { ...Object.fromEntries(Object.entries(extra).map((el) => [extraColumnList.find((col) => col.id === el[0]).name, el[1]])) });
|
119
|
+
});
|
120
|
+
|
121
|
+
// admin.custom_column - metaFormat
|
122
|
+
await Promise.all(extraColumnList.filter((el) => el?.data).map(async (attr) => {
|
123
|
+
const values = [...new Set(rows?.map((el) => el[attr.name]).flat())].filter((el) => el);
|
124
|
+
if (!values.length) return;
|
125
|
+
const cls = await getSelectVal({ name: attr.data, values });
|
126
|
+
if (!cls) return;
|
127
|
+
rows.forEach(el => {
|
128
|
+
const val = el[attr.name]?.map?.(c => cls[c] || c) || cls[el[attr.name]] || el[attr.name];
|
129
|
+
if (!val) return;
|
130
|
+
Object.assign(el, { [val?.color ? `${attr.name}_data` : `${attr.name}_text`]: (val.color ? val : val.text || val) });
|
131
|
+
});
|
132
|
+
}));
|
133
|
+
|
134
|
+
await metaFormat({ funcs, rows, table: params.table });
|
135
|
+
|
136
|
+
const res = {
|
137
|
+
time: Date.now() - time, card: loadTable.card, actions: loadTable.actions, access, total, count: rows.length, pk, form, meta, columns,
|
138
|
+
};
|
139
|
+
const addToken = assignTokens({ rows, funcs, ispublic, uid: 1, loadTable });
|
140
|
+
Object.assign(res, { rows, addToken });
|
141
|
+
|
142
|
+
return res;
|
143
|
+
} catch (err) {
|
144
|
+
return { message: err.toString(), status: 500 };
|
145
|
+
}
|
146
146
|
}
|
@@ -1,28 +1,28 @@
|
|
1
|
-
import getTemplate from "../../templates/funcs/getTemplate.js";
|
2
|
-
import getTableData from "./tableData.js";
|
3
|
-
|
4
|
-
export default async function tableDataId({
|
5
|
-
pg, funcs, params = {}, session = {},
|
6
|
-
}, reply) {
|
7
|
-
const { name, id } = params;
|
8
|
-
|
9
|
-
const data = await getTemplate('pt', `${name}.pt`);
|
10
|
-
|
11
|
-
|
12
|
-
if (!data) {
|
13
|
-
return { message: `invalid template: ${name}.pt`, status: 400 };
|
14
|
-
}
|
15
|
-
|
16
|
-
const { message, status = 500, rows = [] } = await getTableData({ pg, params: { name, id }, session });
|
17
|
-
if (message) {
|
18
|
-
return { message, status };
|
19
|
-
}
|
20
|
-
|
21
|
-
if (!rows.length) {
|
22
|
-
return { message: `data not found: ${name}/${id}`, status: 404 };
|
23
|
-
}
|
24
|
-
|
25
|
-
const htmlContent = await funcs.handlebars.compile(data)(rows[0]);
|
26
|
-
|
27
|
-
return reply.headers({ 'Content-Type': 'text/html; charset=utf-8' }).send(htmlContent);
|
1
|
+
import getTemplate from "../../templates/funcs/getTemplate.js";
|
2
|
+
import getTableData from "./tableData.js";
|
3
|
+
|
4
|
+
export default async function tableDataId({
|
5
|
+
pg, funcs, params = {}, session = {},
|
6
|
+
}, reply) {
|
7
|
+
const { name, id } = params;
|
8
|
+
|
9
|
+
const data = await getTemplate('pt', `${name}.pt`);
|
10
|
+
|
11
|
+
|
12
|
+
if (!data) {
|
13
|
+
return { message: `invalid template: ${name}.pt`, status: 400 };
|
14
|
+
}
|
15
|
+
|
16
|
+
const { message, status = 500, rows = [] } = await getTableData({ pg, params: { name, id }, session });
|
17
|
+
if (message) {
|
18
|
+
return { message, status };
|
19
|
+
}
|
20
|
+
|
21
|
+
if (!rows.length) {
|
22
|
+
return { message: `data not found: ${name}/${id}`, status: 404 };
|
23
|
+
}
|
24
|
+
|
25
|
+
const htmlContent = await funcs.handlebars.compile(data)(rows[0]);
|
26
|
+
|
27
|
+
return reply.headers({ 'Content-Type': 'text/html; charset=utf-8' }).send(htmlContent);
|
28
28
|
}
|
@@ -1,64 +1,64 @@
|
|
1
|
-
import { getTemplate } from "@opengis/fastify-table/utils.js";
|
2
|
-
|
3
|
-
export default async function tableFilter(req) {
|
4
|
-
const time = Date.now();
|
5
|
-
const { pg, funcs = {}, params = {}, session = {} } = req;
|
6
|
-
const { uid } = session.passport?.user || {};
|
7
|
-
|
8
|
-
if (!params.name) {
|
9
|
-
return { message: 'not enouggh params: name', status: 400 };
|
10
|
-
}
|
11
|
-
|
12
|
-
const loadTable = await getTemplate('table', params.name);
|
13
|
-
|
14
|
-
if (!loadTable) {
|
15
|
-
return { message: 'table not found', status: 404 };
|
16
|
-
}
|
17
|
-
|
18
|
-
const { columns } = await funcs.getMeta({ table: loadTable.table });
|
19
|
-
|
20
|
-
const filters = loadTable?.filter_list || loadTable?.filters || loadTable?.filterList || [];
|
21
|
-
filters.forEach(el => {
|
22
|
-
Object.assign(el, { id: el.name || el.id, name: el.name || el.id });
|
23
|
-
});
|
24
|
-
|
25
|
-
// admin.custom_column - user filter
|
26
|
-
const { rows: properties = [] } = await pg.query(`select column_id, name, title, format, data from admin.custom_column where entity=$1 and uid=$2 and filter`, [params.name, uid]);
|
27
|
-
properties.forEach((row) => filters.push({ id: row.name, name: row.name, ua: row.title, type: row.format, data: row.data }));
|
28
|
-
|
29
|
-
await Promise.all(filters.filter((el) => el.data).map(async (el) => {
|
30
|
-
|
31
|
-
const cls = await getTemplate(['cls', 'select'], el.data);
|
32
|
-
const name = el.name || el.id;
|
33
|
-
|
34
|
-
if (!cls?.length || !Array.isArray(cls) || !loadTable.table || !name) return;
|
35
|
-
const { dataTypeID } = columns.find((item) => item.name === name) || {};
|
36
|
-
if (el.extra && el.type === 'select' && Array.isArray(cls)) {
|
37
|
-
const countArr = await pg.query(`select value_text as id, count(*) from setting.extra_data where property_key='${name}' and property_entity='${params.name}' group by value_text`);
|
38
|
-
const options = countArr.rows.map(cel => {
|
39
|
-
const data = cls.find(c => c.id === cel.id);
|
40
|
-
return { ...cel, ...data };
|
41
|
-
});
|
42
|
-
Object.assign(el, { options });
|
43
|
-
}
|
44
|
-
if (!dataTypeID) return;
|
45
|
-
|
46
|
-
const countArr = pg.pgType?.[dataTypeID]?.includes('[]')
|
47
|
-
? await pg.queryCache(`select unnest(${name})::text as id,count(*) from ${loadTable.table} group by unnest(${name})`)
|
48
|
-
: await pg.queryCache(`select ${name}::text as id,count(*) from ${loadTable.table} group by ${name}`);
|
49
|
-
|
50
|
-
const options = countArr.rows.map(cel => {
|
51
|
-
const data = cls.find(c => c.id === cel.id);
|
52
|
-
return { ...cel, ...data };
|
53
|
-
});
|
54
|
-
Object.assign(el, { options });
|
55
|
-
}));
|
56
|
-
|
57
|
-
return {
|
58
|
-
time: Date.now() - time,
|
59
|
-
list: filters,
|
60
|
-
custom: loadTable?.filterCustom?.map(el => ({ label: el.label })),
|
61
|
-
inline: loadTable?.filterInline,
|
62
|
-
state: loadTable?.filterState?.map(el => ({ label: el.label })),
|
63
|
-
};
|
1
|
+
import { getTemplate } from "@opengis/fastify-table/utils.js";
|
2
|
+
|
3
|
+
export default async function tableFilter(req) {
|
4
|
+
const time = Date.now();
|
5
|
+
const { pg, funcs = {}, params = {}, session = {} } = req;
|
6
|
+
const { uid } = session.passport?.user || {};
|
7
|
+
|
8
|
+
if (!params.name) {
|
9
|
+
return { message: 'not enouggh params: name', status: 400 };
|
10
|
+
}
|
11
|
+
|
12
|
+
const loadTable = await getTemplate('table', params.name);
|
13
|
+
|
14
|
+
if (!loadTable) {
|
15
|
+
return { message: 'table not found', status: 404 };
|
16
|
+
}
|
17
|
+
|
18
|
+
const { columns } = await funcs.getMeta({ table: loadTable.table });
|
19
|
+
|
20
|
+
const filters = loadTable?.filter_list || loadTable?.filters || loadTable?.filterList || [];
|
21
|
+
filters.forEach(el => {
|
22
|
+
Object.assign(el, { id: el.name || el.id, name: el.name || el.id });
|
23
|
+
});
|
24
|
+
|
25
|
+
// admin.custom_column - user filter
|
26
|
+
const { rows: properties = [] } = await pg.query(`select column_id, name, title, format, data from admin.custom_column where entity=$1 and uid=$2 and filter`, [params.name, uid]);
|
27
|
+
properties.forEach((row) => filters.push({ id: row.name, name: row.name, ua: row.title, type: row.format, data: row.data }));
|
28
|
+
|
29
|
+
await Promise.all(filters.filter((el) => el.data).map(async (el) => {
|
30
|
+
|
31
|
+
const cls = await getTemplate(['cls', 'select'], el.data);
|
32
|
+
const name = el.name || el.id;
|
33
|
+
|
34
|
+
if (!cls?.length || !Array.isArray(cls) || !loadTable.table || !name) return;
|
35
|
+
const { dataTypeID } = columns.find((item) => item.name === name) || {};
|
36
|
+
if (el.extra && el.type === 'select' && Array.isArray(cls)) {
|
37
|
+
const countArr = await pg.query(`select value_text as id, count(*) from setting.extra_data where property_key='${name}' and property_entity='${params.name}' group by value_text`);
|
38
|
+
const options = countArr.rows.map(cel => {
|
39
|
+
const data = cls.find(c => c.id === cel.id);
|
40
|
+
return { ...cel, ...data };
|
41
|
+
});
|
42
|
+
Object.assign(el, { options });
|
43
|
+
}
|
44
|
+
if (!dataTypeID) return;
|
45
|
+
|
46
|
+
const countArr = pg.pgType?.[dataTypeID]?.includes('[]')
|
47
|
+
? await pg.queryCache(`select unnest(${name})::text as id,count(*) from ${loadTable.table} group by unnest(${name})`)
|
48
|
+
: await pg.queryCache(`select ${name}::text as id,count(*) from ${loadTable.table} group by ${name}`);
|
49
|
+
|
50
|
+
const options = countArr.rows.map(cel => {
|
51
|
+
const data = cls.find(c => c.id === cel.id);
|
52
|
+
return { ...cel, ...data };
|
53
|
+
});
|
54
|
+
Object.assign(el, { options });
|
55
|
+
}));
|
56
|
+
|
57
|
+
return {
|
58
|
+
time: Date.now() - time,
|
59
|
+
list: filters,
|
60
|
+
custom: loadTable?.filterCustom?.map(el => ({ label: el.label })),
|
61
|
+
inline: loadTable?.filterInline,
|
62
|
+
state: loadTable?.filterState?.map(el => ({ label: el.label })),
|
63
|
+
};
|
64
64
|
}
|
@@ -1,31 +1,31 @@
|
|
1
|
-
import setToken from "@opengis/fastify-table/crud/funcs/setToken.js";
|
2
|
-
|
3
|
-
export default function assignTokens({
|
4
|
-
rows = [], funcs = {}, ispublic, uid, loadTable = {},
|
5
|
-
}) {
|
6
|
-
if (funcs.config?.security?.disableToken) return;
|
7
|
-
|
8
|
-
if (!funcs.config?.auth?.disable && !ispublic && !uid) throw new Error('empty user');
|
9
|
-
if (!loadTable?.table || !(loadTable?.form || loadTable?.add_form)) return null;
|
10
|
-
|
11
|
-
const form = loadTable?.form || loadTable?.add_form;
|
12
|
-
const addTokens = setToken({
|
13
|
-
ids: [JSON.stringify({ add: loadTable.table, form })],
|
14
|
-
mode: 'a',
|
15
|
-
uid: funcs.config?.auth?.disable || ispublic ? '1' : uid,
|
16
|
-
array: 1,
|
17
|
-
});
|
18
|
-
if (!rows.length) return addTokens[0];
|
19
|
-
|
20
|
-
rows.forEach((row) => {
|
21
|
-
const editTokens = setToken({
|
22
|
-
ids: [JSON.stringify({ id: row.id, table: loadTable.table, form })],
|
23
|
-
mode: 'w',
|
24
|
-
uid: funcs.config?.auth?.disable || ispublic ? '1' : uid,
|
25
|
-
array: 1,
|
26
|
-
});
|
27
|
-
Object.assign(row, { token: editTokens[0] });
|
28
|
-
});
|
29
|
-
return addTokens[0];
|
30
|
-
|
1
|
+
import setToken from "@opengis/fastify-table/crud/funcs/setToken.js";
|
2
|
+
|
3
|
+
export default function assignTokens({
|
4
|
+
rows = [], funcs = {}, ispublic, uid, loadTable = {},
|
5
|
+
}) {
|
6
|
+
if (funcs.config?.security?.disableToken) return;
|
7
|
+
|
8
|
+
if (!funcs.config?.auth?.disable && !ispublic && !uid) throw new Error('empty user');
|
9
|
+
if (!loadTable?.table || !(loadTable?.form || loadTable?.add_form)) return null;
|
10
|
+
|
11
|
+
const form = loadTable?.form || loadTable?.add_form;
|
12
|
+
const addTokens = setToken({
|
13
|
+
ids: [JSON.stringify({ add: loadTable.table, form })],
|
14
|
+
mode: 'a',
|
15
|
+
uid: funcs.config?.auth?.disable || ispublic ? '1' : uid,
|
16
|
+
array: 1,
|
17
|
+
});
|
18
|
+
if (!rows.length) return addTokens[0];
|
19
|
+
|
20
|
+
rows.forEach((row) => {
|
21
|
+
const editTokens = setToken({
|
22
|
+
ids: [JSON.stringify({ id: row.id, table: loadTable.table, form })],
|
23
|
+
mode: 'w',
|
24
|
+
uid: funcs.config?.auth?.disable || ispublic ? '1' : uid,
|
25
|
+
array: 1,
|
26
|
+
});
|
27
|
+
Object.assign(row, { token: editTokens[0] });
|
28
|
+
});
|
29
|
+
return addTokens[0];
|
30
|
+
|
31
31
|
}
|
@@ -1,22 +1,22 @@
|
|
1
|
-
import { getTemplate } from "@opengis/fastify-table/utils.js";
|
2
|
-
|
3
|
-
export default async function getColumns({
|
4
|
-
columns = [], params = {}, opt = {}, loadTable = {}, form, table, dbColumns = [], mode = 'table',
|
5
|
-
}) {
|
6
|
-
const columnList = dbColumns.map((el) => el.name || el).join(',');
|
7
|
-
if (mode === 'table') {
|
8
|
-
const cols = columns.filter((el) => el?.name !== 'geom').map((el) => el?.name || el).join(',');
|
9
|
-
return { cols, columnList };
|
10
|
-
}
|
11
|
-
// card / edit form
|
12
|
-
const schema = await getTemplate('form', opt?.form || form) || {};
|
13
|
-
// skip DataTable from another table
|
14
|
-
const extraKeys = Object.keys(schema)?.filter((key) => schema[key]?.type === 'DataTable' && schema[key]?.table && schema[key]?.parent_id && schema[key]?.colModel?.length);
|
15
|
-
// skip non-existing columns
|
16
|
-
const { fields = [] } = !loadTable?.table ? await pg.query(`select * from ${table || opt?.table || params.table} limit 0`) : {};
|
17
|
-
const cols = loadTable?.table
|
18
|
-
? Object.keys(schema || {}).filter((col) => columnList.includes(col) && !extraKeys.includes(col))?.join(',')
|
19
|
-
: fields.map((el) => (el?.name?.includes('geom') ? `st_asgeojson(${el.name})::json as "${el.name}"` : `"${el?.name}"`)).join(',');
|
20
|
-
|
21
|
-
return { cols, columnList, extraKeys, schema };
|
1
|
+
import { getTemplate } from "@opengis/fastify-table/utils.js";
|
2
|
+
|
3
|
+
export default async function getColumns({
|
4
|
+
columns = [], params = {}, opt = {}, loadTable = {}, form, table, dbColumns = [], mode = 'table',
|
5
|
+
}) {
|
6
|
+
const columnList = dbColumns.map((el) => el.name || el).join(',');
|
7
|
+
if (mode === 'table') {
|
8
|
+
const cols = columns.filter((el) => el?.name !== 'geom').map((el) => el?.name || el).join(',');
|
9
|
+
return { cols, columnList };
|
10
|
+
}
|
11
|
+
// card / edit form
|
12
|
+
const schema = await getTemplate('form', opt?.form || form) || {};
|
13
|
+
// skip DataTable from another table
|
14
|
+
const extraKeys = Object.keys(schema)?.filter((key) => schema[key]?.type === 'DataTable' && schema[key]?.table && schema[key]?.parent_id && schema[key]?.colModel?.length);
|
15
|
+
// skip non-existing columns
|
16
|
+
const { fields = [] } = !loadTable?.table ? await pg.query(`select * from ${table || opt?.table || params.table} limit 0`) : {};
|
17
|
+
const cols = loadTable?.table
|
18
|
+
? Object.keys(schema || {}).filter((col) => columnList.includes(col) && !extraKeys.includes(col))?.join(',')
|
19
|
+
: fields.map((el) => (el?.name?.includes('geom') ? `st_asgeojson(${el.name})::json as "${el.name}"` : `"${el?.name}"`)).join(',');
|
20
|
+
|
21
|
+
return { cols, columnList, extraKeys, schema };
|
22
22
|
}
|
@@ -1,15 +1,15 @@
|
|
1
|
-
|
2
|
-
import tableData from "./controllers/tableData.js";
|
3
|
-
// import tableDataId from "./controllers/tableDataId.js";
|
4
|
-
import cardData from "./controllers/cardData.js";
|
5
|
-
import cardTabData from './controllers/cardTabData.js';
|
6
|
-
import tableFilter from "./controllers/tableFilter.js";
|
7
|
-
|
8
|
-
import { tableDataSchema } from './schema.js';
|
9
|
-
|
10
|
-
export default async function route(fastify) {
|
11
|
-
fastify.get(`/table-data/:table`, { schema: tableDataSchema }, tableData);
|
12
|
-
fastify.get(`/card-data/:token`, cardTabData);
|
13
|
-
fastify.get(`/table-data/:table/:id`, cardData);
|
14
|
-
fastify.get(`/table-filter/:name`, tableFilter);
|
15
|
-
}
|
1
|
+
|
2
|
+
import tableData from "./controllers/tableData.js";
|
3
|
+
// import tableDataId from "./controllers/tableDataId.js";
|
4
|
+
import cardData from "./controllers/cardData.js";
|
5
|
+
import cardTabData from './controllers/cardTabData.js';
|
6
|
+
import tableFilter from "./controllers/tableFilter.js";
|
7
|
+
|
8
|
+
import { tableDataSchema } from './schema.js';
|
9
|
+
|
10
|
+
export default async function route(fastify) {
|
11
|
+
fastify.get(`/table-data/:table`, { schema: tableDataSchema }, tableData);
|
12
|
+
fastify.get(`/card-data/:token`, cardTabData);
|
13
|
+
fastify.get(`/table-data/:table/:id`, cardData);
|
14
|
+
fastify.get(`/table-filter/:name`, tableFilter);
|
15
|
+
}
|
@@ -1,7 +1,7 @@
|
|
1
|
-
const tableDataSchema = {
|
2
|
-
querystring: {
|
3
|
-
limit: { type: 'integer' },
|
4
|
-
}
|
5
|
-
};
|
6
|
-
export { tableDataSchema }
|
7
|
-
export default null;
|
1
|
+
const tableDataSchema = {
|
2
|
+
querystring: {
|
3
|
+
limit: { type: 'integer' },
|
4
|
+
}
|
5
|
+
};
|
6
|
+
export { tableDataSchema }
|
7
|
+
export default null;
|