@opengis/admin 0.1.66 → 0.1.67

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 (115) hide show
  1. package/README.md +29 -29
  2. package/config.js +4 -4
  3. package/dist/IconChevronDown-DN0s3TF_.js +26 -0
  4. package/dist/{add-page-YonHQsF2.js → add-page-Cm4aSGoA.js} +1 -1
  5. package/dist/{admin-interface-DSR1im5I.js → admin-interface-DUuz9KgB.js} +533 -405
  6. package/dist/{admin-view-WZhYBXYw.js → admin-view-MSa57inW.js} +128 -147
  7. package/dist/admin.js +1 -1
  8. package/dist/admin.umd.cjs +86 -86
  9. package/dist/card-page-B1zuuqAR.js +275 -0
  10. package/dist/{card-view-DYhMgpIH.js → card-view-Bzt2AvI2.js} +1 -1
  11. package/dist/{edit-page-D8fMSwEp.js → edit-page-DoY4S7v6.js} +1 -1
  12. package/dist/{import-file-Do-GQQHc.js → import-file-B80Ws8by.js} +6797 -6812
  13. package/dist/style.css +1 -1
  14. package/module/settings/card/admin.roles.table/access.hbs +27 -27
  15. package/module/settings/card/admin.roles.table/general_info.hbs +16 -16
  16. package/module/settings/card/admin.roles.table/index.yml +14 -14
  17. package/module/settings/card/admin.roles.table/users.hbs +27 -27
  18. package/module/settings/card/admin.routes.table/general_info.hbs +40 -40
  19. package/module/settings/card/admin.routes.table/index.yml +8 -8
  20. package/module/settings/card/admin.routes.table/users.hbs +33 -33
  21. package/module/settings/card/admin.users.table/general_info.hbs +25 -25
  22. package/module/settings/card/admin.users.table/index.yml +12 -12
  23. package/module/settings/card/admin.users.table/logs.hbs +30 -30
  24. package/module/settings/card/admin.users.table/user_roles.hbs +24 -24
  25. package/module/settings/cls/core.actions.json +13 -13
  26. package/module/settings/cls/core.scope.json +13 -13
  27. package/module/settings/cls/properties.site_status.json +13 -13
  28. package/module/settings/cls/properties.widget_status.json +13 -13
  29. package/module/settings/cls/users.user_type.json +13 -13
  30. package/module/settings/form/admin.access.form.json +36 -36
  31. package/module/settings/form/admin.custom_column.form.json +71 -71
  32. package/module/settings/form/admin.properties.form.json +15 -15
  33. package/module/settings/form/admin.roles.form.json +19 -19
  34. package/module/settings/form/admin.routes.form.json +25 -25
  35. package/module/settings/form/admin.user_properties.form.json +15 -15
  36. package/module/settings/form/admin.user_roles.form.json +21 -21
  37. package/module/settings/form/admin.users.form.json +150 -150
  38. package/module/settings/form/user.user_roles.form.json +13 -13
  39. package/module/settings/interface/admin.properties.json +4 -4
  40. package/module/settings/interface/admin.roles.json +4 -4
  41. package/module/settings/interface/admin.routes.json +4 -4
  42. package/module/settings/interface/admin.users.json +4 -4
  43. package/module/settings/menu.json +50 -50
  44. package/module/settings/select/core.roles.json +2 -2
  45. package/module/settings/select/core.routes.sql +1 -1
  46. package/module/settings/select/core.user_uid.sql +1 -1
  47. package/module/settings/table/admin.access.table.json +77 -77
  48. package/module/settings/table/admin.custom_column.table.json +94 -94
  49. package/module/settings/table/admin.properties.table.json +33 -33
  50. package/module/settings/table/admin.roles.table.json +58 -58
  51. package/module/settings/table/admin.routes.table.json +67 -67
  52. package/module/settings/table/admin.user_properties.table.json +28 -28
  53. package/module/settings/table/admin.user_roles.table.json +66 -66
  54. package/module/settings/table/admin.users.table.json +119 -119
  55. package/package.json +82 -80
  56. package/plugin.js +100 -100
  57. package/server/helpers/controllers/badge.js +11 -11
  58. package/server/helpers/controllers/hb.js +2 -2
  59. package/server/helpers/controllers/map.js +2 -2
  60. package/server/helpers/controllers/mls.js +2 -2
  61. package/server/helpers/controllers/vue.js +2 -2
  62. package/server/helpers/index.mjs +13 -13
  63. package/server/plugins/adminHook.js +165 -165
  64. package/server/plugins/cron.js +10 -10
  65. package/server/plugins/docs.js +28 -28
  66. package/server/plugins/hook.js +185 -185
  67. package/server/plugins/vite.js +74 -69
  68. package/server/routes/calendar/controllers/calendar.data.js +88 -88
  69. package/server/routes/calendar/index.mjs +17 -17
  70. package/server/routes/data/controllers/cardData.js +57 -57
  71. package/server/routes/data/controllers/cardTabData.js +49 -49
  72. package/server/routes/data/controllers/funcs/getFilterSQL/index.js +92 -92
  73. package/server/routes/data/controllers/funcs/getFilterSQL/util/formatValue.js +170 -170
  74. package/server/routes/data/controllers/funcs/getFilterSQL/util/getCustomQuery.js +13 -13
  75. package/server/routes/data/controllers/funcs/getFilterSQL/util/getFilterQuery.js +64 -64
  76. package/server/routes/data/controllers/funcs/getFilterSQL/util/getOptimizedQuery.js +12 -12
  77. package/server/routes/data/controllers/funcs/getFilterSQL/util/getTableSql.js +34 -34
  78. package/server/routes/data/controllers/tableData.js +112 -112
  79. package/server/routes/data/controllers/tableDataId.js +27 -27
  80. package/server/routes/data/controllers/tableFilter.js +63 -63
  81. package/server/routes/data/controllers/utils/assignTokens.js +30 -30
  82. package/server/routes/data/controllers/utils/getColumns.js +8 -8
  83. package/server/routes/data/index.mjs +15 -15
  84. package/server/routes/data/schema.js +7 -7
  85. package/server/routes/menu/controllers/getMenu.js +51 -51
  86. package/server/routes/menu/index.mjs +5 -5
  87. package/server/routes/notifications/controllers/readNotifications.js +30 -30
  88. package/server/routes/notifications/controllers/userNotifications.js +64 -64
  89. package/server/routes/notifications/hook/onWidgetSet.js +57 -57
  90. package/server/routes/notifications/index.mjs +40 -40
  91. package/server/routes/properties/controllers/admin.properties.get.js +29 -29
  92. package/server/routes/properties/controllers/user.properties.get.js +34 -34
  93. package/server/routes/properties/controllers/user.properties.post.js +30 -30
  94. package/server/routes/properties/funcs/getSettings.js +56 -56
  95. package/server/routes/properties/funcs/setSettings.js +44 -44
  96. package/server/routes/properties/funcs/utils/dataInsert.js +26 -26
  97. package/server/routes/properties/index.mjs +26 -26
  98. package/server/routes/root.mjs +3 -3
  99. package/server/routes/templates/controllers/getTemplate.js +22 -22
  100. package/server/routes/templates/index.mjs +14 -14
  101. package/server/templates/cls/itree.recrzone_category.json +73 -73
  102. package/server/templates/cls/test.json +9 -9
  103. package/server/templates/form/admin.user_cls.data.form.json +49 -49
  104. package/server/templates/form/admin.user_group_rel.form.json +21 -21
  105. package/server/templates/form/cp_building.form.json +32 -32
  106. package/server/templates/form/form-user-pass.json +10 -10
  107. package/server/templates/form/form-user_group.json +39 -39
  108. package/server/templates/form/form-users.json +156 -156
  109. package/server/templates/form/user_group_access.form.json +22 -22
  110. package/server/templates/select/account_id.json +2 -2
  111. package/server/templates/table/gis.dataset.table.json +43 -43
  112. package/server/templates/table/management.user_group.table.json +112 -112
  113. package/server/templates/table/management.users.table.json +126 -126
  114. package/utils.js +21 -21
  115. package/dist/card-page-BH8lGOKk.js +0 -230
@@ -1,28 +1,28 @@
1
- 'use strict'
2
-
3
- import path, { dirname } from 'path';
4
- import { fileURLToPath } from 'url';
5
- import fs from 'fs';
6
-
7
- const dir = dirname(fileURLToPath(import.meta.url));
8
- const root = `${dir}/../../`;
9
-
10
-
11
- async function plugin(fastify, opts) {
12
- fastify.get('/docs*', async (req, reply) => {
13
- if (!fs.existsSync(path.join(root, 'docs/.vitepress/dist/'))) {
14
- return reply.status(404).send('docs not exists');
15
- }
16
- const { params } = req;
17
- const url = params['*']
18
- const filePath = url && url[url.length - 1] !== '/' ? path.join(root, 'docs/.vitepress/dist/', url) : path.join(root, 'docs/.vitepress/dist/', url, 'index.html')
19
- const ext = path.extname(filePath);
20
- const mime = {
21
- '.js': 'text/javascript', '.css': 'text/css', '.woff2': 'application/font-woff', '.png': 'image/png', '.svg': 'image/svg+xml', '.jpg': 'image/jpg'
22
- }[ext];
23
- const stream = fs.createReadStream(filePath);
24
- return mime ? reply.type(mime).send(stream) : stream;
25
-
26
- })
27
- }
28
- export default plugin;
1
+ 'use strict'
2
+
3
+ import path, { dirname } from 'path';
4
+ import { fileURLToPath } from 'url';
5
+ import fs from 'fs';
6
+
7
+ const dir = dirname(fileURLToPath(import.meta.url));
8
+ const root = `${dir}/../../`;
9
+
10
+
11
+ async function plugin(fastify, opts) {
12
+ fastify.get('/docs*', async (req, reply) => {
13
+ if (!fs.existsSync(path.join(root, 'docs/.vitepress/dist/'))) {
14
+ return reply.status(404).send('docs not exists');
15
+ }
16
+ const { params } = req;
17
+ const url = params['*']
18
+ const filePath = url && url[url.length - 1] !== '/' ? path.join(root, 'docs/.vitepress/dist/', url) : path.join(root, 'docs/.vitepress/dist/', url, 'index.html')
19
+ const ext = path.extname(filePath);
20
+ const mime = {
21
+ '.js': 'text/javascript', '.css': 'text/css', '.woff2': 'application/font-woff', '.png': 'image/png', '.svg': 'image/svg+xml', '.jpg': 'image/jpg'
22
+ }[ext];
23
+ const stream = fs.createReadStream(filePath);
24
+ return mime ? reply.type(mime).send(stream) : stream;
25
+
26
+ })
27
+ }
28
+ export default plugin;
@@ -1,186 +1,186 @@
1
- import { addHook, getToken, setToken, getTemplate, config, pgClients } from '@opengis/fastify-table/utils.js';
2
-
3
- async function getTokenData({
4
- mode = 'w', token, uid,
5
- }) {
6
- if (!token) {
7
- return { message: 'not enough params: token', status: 400 };
8
- }
9
-
10
- if (!uid && !config?.auth?.disable) {
11
- return { message: 'access restricted: uid', status: 403 };
12
- }
13
-
14
- const opt = await getToken({
15
- uid, token, mode, json: 1,
16
- });
17
-
18
- if (!opt && !config?.local) {
19
- return { message: 'access restricted: edit', status: 403 };
20
- }
21
- return opt;
22
- }
23
-
24
- export default async function plugin(fastify) {
25
-
26
- addHook('preTable', async ({ table, user = {} }) => {
27
- const { uid } = config?.auth?.disable ? { uid: '1' } : user || {};
28
- const opt = await getTokenData({ mode: 'w', token: table, uid });
29
- return opt;
30
- });
31
- addHook('preCard', async ({ table, user = {} }) => {
32
- const { uid } = config?.auth?.disable ? { uid: '1' } : user || {};
33
- const opt = await getTokenData({ mode: 'w', token: table, uid });
34
- return opt;
35
- });
36
- addHook('preData', async ({ table, id, user = {} }) => {
37
- const { uid } = config?.auth?.disable ? { uid: '1' } : user || {};
38
- const opt = await getTokenData({ mode: 'w', token: table, uid });
39
- return opt;
40
- });
41
- addHook('preForm', async ({ form, user }) => {
42
- const { uid } = config?.auth?.disable ? { uid: '1' } : user || {};
43
- const opt = await getTokenData({ mode: 'w', token: form, uid });
44
- return opt;
45
- });
46
- addHook('preInsert', async ({ table, user }) => {
47
- const { uid } = config?.auth?.disable ? { uid: '1' } : user || {};
48
- const opt = await getTokenData({ mode: 'a', token: table, uid });
49
- return opt;
50
- });
51
- addHook('preUpdate', async ({ table, id, user }) => {
52
- const { uid } = config?.auth?.disable ? { uid: '1' } : user || {};
53
- const opt = await getTokenData({ mode: 'w', token: table, uid });
54
- return opt;
55
- });
56
- addHook('preDelete', async ({ table, id, user }) => {
57
- const { uid } = config?.auth?.disable ? { uid: '1' } : user || {};
58
- const opt = await getTokenData({ mode: 'w', token: table, uid });
59
- return opt;
60
- });
61
-
62
- addHook('afterTable', async ({ table, res = {}, payload: rows = [], user = {} }) => {
63
- const { client: pg } = pgClients || {};
64
- const loadTable = await getTemplate('table', table);
65
- const { uid } = config?.auth?.disable ? { uid: '1' } : user;
66
- if (!uid || !table || !pg?.pk?.[table] || !rows.length || !loadTable?.table) return;
67
-
68
- // admin.custom_column - user column data
69
- const { rows: properties = [] } = await pg.query(`select column_id, name, title, format, data from admin.custom_column
70
- where _table and entity=$1 and uid=$2`, [table, uid]);
71
- const extraColumnList = properties.map((row) => ({ id: row.column_id, name: row.name, title: row.title, format: row.format, data: row.data }));
72
- if (!extraColumnList?.length) return;
73
-
74
- if (res?.columns?.length) {
75
- extraColumnList.forEach((col) => res.columns.push(col));
76
- }
77
-
78
- 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
79
- where property_entity=$1 and property_id=any($2) and object_id=any($3) group by object_id`, [table, extraColumnList?.map((el) => el.id), rows.map((el) => el.id)]);
80
-
81
- if (!extraData?.length) {
82
- // Object.assign(rows?.[0] || {}, { ...extraColumnList.reduce((acc, curr) => Object.assign(acc, { [curr.name]: null }), {}) });
83
- return;
84
- }
85
-
86
- rows.filter((row) => extraData.map((el) => el?.object_id).includes(row.id)).forEach((row) => {
87
- const { extra = {} } = extraData.find((el) => el.object_id === row.id);
88
- Object.assign(row, { ...Object.fromEntries(Object.entries(extra).map((el) => [extraColumnList.find((col) => col.id === el[0]).name, el[1]])) });
89
- });
90
-
91
- // admin.custom_column - metaFormat
92
- await Promise.all(extraColumnList.filter((el) => el?.data).map(async (attr) => {
93
- const values = [...new Set(rows?.map((el) => el[attr.name]).flat())].filter((el) => el);
94
- if (!values.length) return;
95
- const cls = await getSelectVal({ name: attr.data, values });
96
- if (!cls) return;
97
- rows.forEach(el => {
98
- const val = el[attr.name]?.map?.(c => cls[c] || c) || cls[el[attr.name]] || el[attr.name];
99
- if (!val) return;
100
- Object.assign(el, { [val?.color ? `${attr.name}_data` : `${attr.name}_text`]: (val.color ? val : val.text || val) });
101
- });
102
- }));
103
- });
104
-
105
- // extract table from form token for user columns - p.2 - read (refactor to global token)
106
- addHook('preTemplate', async ({ name, type, user = {} }) => {
107
- if (!name || !type) return;
108
- const { uid } = config?.auth?.disable ? { uid: '1' } : user;
109
- const tokenData = await getToken({
110
- uid, token: name, mode: 'w', json: 1,
111
- }) // edit?
112
- || await getToken({
113
- uid, token: name, mode: 'a', json: 1,
114
- }) || {}; // add?
115
- return { name: tokenData?.[type] };
116
- });
117
-
118
- addHook('afterTemplate', async ({ name, type, payload: data = {}, user = {} }) => {
119
- const { client: pg } = pgClients || {};
120
- const { uid } = config?.auth?.disable ? { uid: '1' } : user;
121
- // extract table from form token for user columns - p.1 - assign (refactor to global token)
122
- if (!uid || !data || type !== 'form' || !name) return null;
123
-
124
- const { form, id, table } = await getToken({
125
- uid, token: name, mode: 'w', json: 1,
126
- }) // edit?
127
- || await getToken({
128
- uid, token: name, mode: 'a', json: 1,
129
- }) || {}; // add?
130
-
131
- const { rows: properties = [] } = await pg.query(`select name, title, format, data from admin.custom_column
132
- where entity=$1 and uid=$2`, [table || name, uid]);
133
-
134
- await Promise.all(properties.map(async (el) => {
135
- const clsData = el.data ? await getTemplate(['cls', 'select'], el.data) : undefined;
136
- const type = clsData ? 'Select' : ({ date: 'DatePicker' }[el.format] || 'Text');
137
- Object.assign(data?.schema || data || {}, { [el.name]: { type, ua: el.title, data: el.data, options: type === 'Select' && Array.isArray(clsData) && clsData?.length ? clsData : undefined, extra: 1 } });
138
- }));
139
- });
140
-
141
- addHook('afterUpdate', async ({ table, body = {}, payload: res = {}, user = {} }) => {
142
- const { client: pg } = pgClients || {};
143
- const { uid } = config?.auth?.disable ? { uid: '1' } : user;
144
- if (!uid || !table || !Object.keys(body)?.length) return null;
145
-
146
- const loadTable = await getTemplate('table', table);
147
- if (!pg.pk[loadTable?.table || table]) return null;
148
- const pk = pg.pk[loadTable?.table || table];
149
- const id = res[pk];
150
-
151
- const { rows: properties = [] } = await pg.query(`select column_id, name, title, format, data from admin.custom_column
152
- where entity=$1 and uid=$2`, [table, uid]);
153
-
154
- if (!id || !properties?.length) return null;
155
-
156
- const q = `delete from crm.extra_data where property_entity='${table}' and object_id='${id}';${properties
157
- .filter((el) => Object.keys(body).includes(el.name))
158
- .map((el) => `insert into crm.extra_data(property_id,property_key,property_entity,object_id,${el.format?.toLowerCase() === 'date' ? 'value_date' : 'value_text'})
159
- select '${el.column_id}', '${el.name}', '${table}', '${id}', ${el.format?.toLowerCase() === 'date' ? `'${body[el.name]}'::timestamp without time zone` : `'${body[el.name]}'::text`}`)
160
- .join(';\n') || ''}`;
161
- return pg.query(q);
162
- });
163
-
164
- addHook('afterInsert', async ({ table, body = {}, payload: res = {}, user = {} }) => {
165
- const { client: pg } = pgClients || {};
166
- const { uid } = config?.auth?.disable ? { uid: '1' } : user;
167
- if (!uid || !table || !Object.keys(body)?.length) return null;
168
-
169
- const loadTable = await getTemplate('table', table);
170
- if (!pg.pk[loadTable?.table || table]) return null;
171
- const pk = pg.pk[loadTable?.table || table];
172
- const id = res.rows?.[0]?.[pk];
173
-
174
- const { rows: properties = [] } = await pg.query(`select column_id, name, title, format, data from admin.custom_column
175
- where entity=$1 and uid=$2`, [table, uid]);
176
-
177
- if (!id || !properties?.length) return null;
178
-
179
- const q = properties
180
- .filter((el) => Object.keys(body).includes(el.name))
181
- .map((el) => `insert into crm.extra_data(property_id,property_key,property_entity,object_id,${el.format?.toLowerCase() === 'date' ? 'value_date' : 'value_text'})
182
- select '${el.column_id}', '${el.name}', '${table}', '${id}', ${el.format?.toLowerCase() === 'date' ? `'${body[el.name]}'::timestamp without time zone` : `'${body[el.name]}'::text`}`)
183
- .join(';\n');
184
- return pg.query(q);
185
- });
1
+ import { addHook, getToken, setToken, getTemplate, config, pgClients } from '@opengis/fastify-table/utils.js';
2
+
3
+ async function getTokenData({
4
+ mode = 'w', token, uid,
5
+ }) {
6
+ if (!token) {
7
+ return { message: 'not enough params: token', status: 400 };
8
+ }
9
+
10
+ if (!uid && !config?.auth?.disable) {
11
+ return { message: 'access restricted: uid', status: 403 };
12
+ }
13
+
14
+ const opt = await getToken({
15
+ uid, token, mode, json: 1,
16
+ });
17
+
18
+ if (!opt && !config?.local) {
19
+ return { message: 'access restricted: edit', status: 403 };
20
+ }
21
+ return opt;
22
+ }
23
+
24
+ export default async function plugin(fastify) {
25
+
26
+ addHook('preTable', async ({ table, user = {} }) => {
27
+ const { uid } = config?.auth?.disable ? { uid: '1' } : user || {};
28
+ const opt = await getTokenData({ mode: 'w', token: table, uid });
29
+ return opt;
30
+ });
31
+ addHook('preCard', async ({ table, user = {} }) => {
32
+ const { uid } = config?.auth?.disable ? { uid: '1' } : user || {};
33
+ const opt = await getTokenData({ mode: 'w', token: table, uid });
34
+ return opt;
35
+ });
36
+ addHook('preData', async ({ table, id, user = {} }) => {
37
+ const { uid } = config?.auth?.disable ? { uid: '1' } : user || {};
38
+ const opt = await getTokenData({ mode: 'w', token: table, uid });
39
+ return opt;
40
+ });
41
+ addHook('preForm', async ({ form, user }) => {
42
+ const { uid } = config?.auth?.disable ? { uid: '1' } : user || {};
43
+ const opt = await getTokenData({ mode: 'w', token: form, uid });
44
+ return opt;
45
+ });
46
+ addHook('preInsert', async ({ table, user }) => {
47
+ const { uid } = config?.auth?.disable ? { uid: '1' } : user || {};
48
+ const opt = await getTokenData({ mode: 'a', token: table, uid });
49
+ return opt;
50
+ });
51
+ addHook('preUpdate', async ({ table, id, user }) => {
52
+ const { uid } = config?.auth?.disable ? { uid: '1' } : user || {};
53
+ const opt = await getTokenData({ mode: 'w', token: table, uid });
54
+ return opt;
55
+ });
56
+ addHook('preDelete', async ({ table, id, user }) => {
57
+ const { uid } = config?.auth?.disable ? { uid: '1' } : user || {};
58
+ const opt = await getTokenData({ mode: 'w', token: table, uid });
59
+ return opt;
60
+ });
61
+
62
+ addHook('afterTable', async ({ table, res = {}, payload: rows = [], user = {} }) => {
63
+ const { client: pg } = pgClients || {};
64
+ const loadTable = await getTemplate('table', table);
65
+ const { uid } = config?.auth?.disable ? { uid: '1' } : user;
66
+ if (!uid || !table || !pg?.pk?.[table] || !rows.length || !loadTable?.table) return;
67
+
68
+ // admin.custom_column - user column data
69
+ const { rows: properties = [] } = await pg.query(`select column_id, name, title, format, data from admin.custom_column
70
+ where _table and entity=$1 and uid=$2`, [table, uid]);
71
+ const extraColumnList = properties.map((row) => ({ id: row.column_id, name: row.name, title: row.title, format: row.format, data: row.data }));
72
+ if (!extraColumnList?.length) return;
73
+
74
+ if (res?.columns?.length) {
75
+ extraColumnList.forEach((col) => res.columns.push(col));
76
+ }
77
+
78
+ 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
79
+ where property_entity=$1 and property_id=any($2) and object_id=any($3) group by object_id`, [table, extraColumnList?.map((el) => el.id), rows.map((el) => el.id)]);
80
+
81
+ if (!extraData?.length) {
82
+ // Object.assign(rows?.[0] || {}, { ...extraColumnList.reduce((acc, curr) => Object.assign(acc, { [curr.name]: null }), {}) });
83
+ return;
84
+ }
85
+
86
+ rows.filter((row) => extraData.map((el) => el?.object_id).includes(row.id)).forEach((row) => {
87
+ const { extra = {} } = extraData.find((el) => el.object_id === row.id);
88
+ Object.assign(row, { ...Object.fromEntries(Object.entries(extra).map((el) => [extraColumnList.find((col) => col.id === el[0]).name, el[1]])) });
89
+ });
90
+
91
+ // admin.custom_column - metaFormat
92
+ await Promise.all(extraColumnList.filter((el) => el?.data).map(async (attr) => {
93
+ const values = [...new Set(rows?.map((el) => el[attr.name]).flat())].filter((el) => el);
94
+ if (!values.length) return;
95
+ const cls = await getSelectVal({ name: attr.data, values });
96
+ if (!cls) return;
97
+ rows.forEach(el => {
98
+ const val = el[attr.name]?.map?.(c => cls[c] || c) || cls[el[attr.name]] || el[attr.name];
99
+ if (!val) return;
100
+ Object.assign(el, { [val?.color ? `${attr.name}_data` : `${attr.name}_text`]: (val.color ? val : val.text || val) });
101
+ });
102
+ }));
103
+ });
104
+
105
+ // extract table from form token for user columns - p.2 - read (refactor to global token)
106
+ addHook('preTemplate', async ({ name, type, user = {} }) => {
107
+ if (!name || !type) return;
108
+ const { uid } = config?.auth?.disable ? { uid: '1' } : user;
109
+ const tokenData = await getToken({
110
+ uid, token: name, mode: 'w', json: 1,
111
+ }) // edit?
112
+ || await getToken({
113
+ uid, token: name, mode: 'a', json: 1,
114
+ }) || {}; // add?
115
+ return { name: tokenData?.[type] };
116
+ });
117
+
118
+ addHook('afterTemplate', async ({ name, type, payload: data = {}, user = {} }) => {
119
+ const { client: pg } = pgClients || {};
120
+ const { uid } = config?.auth?.disable ? { uid: '1' } : user;
121
+ // extract table from form token for user columns - p.1 - assign (refactor to global token)
122
+ if (!uid || !data || type !== 'form' || !name) return null;
123
+
124
+ const { form, id, table } = await getToken({
125
+ uid, token: name, mode: 'w', json: 1,
126
+ }) // edit?
127
+ || await getToken({
128
+ uid, token: name, mode: 'a', json: 1,
129
+ }) || {}; // add?
130
+
131
+ const { rows: properties = [] } = await pg.query(`select name, title, format, data from admin.custom_column
132
+ where entity=$1 and uid=$2`, [table || name, uid]);
133
+
134
+ await Promise.all(properties.map(async (el) => {
135
+ const clsData = el.data ? await getTemplate(['cls', 'select'], el.data) : undefined;
136
+ const type = clsData ? 'Select' : ({ date: 'DatePicker' }[el.format] || 'Text');
137
+ Object.assign(data?.schema || data || {}, { [el.name]: { type, ua: el.title, data: el.data, options: type === 'Select' && Array.isArray(clsData) && clsData?.length ? clsData : undefined, extra: 1 } });
138
+ }));
139
+ });
140
+
141
+ addHook('afterUpdate', async ({ table, body = {}, payload: res = {}, user = {} }) => {
142
+ const { client: pg } = pgClients || {};
143
+ const { uid } = config?.auth?.disable ? { uid: '1' } : user;
144
+ if (!uid || !table || !Object.keys(body)?.length) return null;
145
+
146
+ const loadTable = await getTemplate('table', table);
147
+ if (!pg.pk[loadTable?.table || table]) return null;
148
+ const pk = pg.pk[loadTable?.table || table];
149
+ const id = res[pk];
150
+
151
+ const { rows: properties = [] } = await pg.query(`select column_id, name, title, format, data from admin.custom_column
152
+ where entity=$1 and uid=$2`, [table, uid]);
153
+
154
+ if (!id || !properties?.length) return null;
155
+
156
+ const q = `delete from crm.extra_data where property_entity='${table}' and object_id='${id}';${properties
157
+ .filter((el) => Object.keys(body).includes(el.name))
158
+ .map((el) => `insert into crm.extra_data(property_id,property_key,property_entity,object_id,${el.format?.toLowerCase() === 'date' ? 'value_date' : 'value_text'})
159
+ select '${el.column_id}', '${el.name}', '${table}', '${id}', ${el.format?.toLowerCase() === 'date' ? `'${body[el.name]}'::timestamp without time zone` : `'${body[el.name]}'::text`}`)
160
+ .join(';\n') || ''}`;
161
+ return pg.query(q);
162
+ });
163
+
164
+ addHook('afterInsert', async ({ table, body = {}, payload: res = {}, user = {} }) => {
165
+ const { client: pg } = pgClients || {};
166
+ const { uid } = config?.auth?.disable ? { uid: '1' } : user;
167
+ if (!uid || !table || !Object.keys(body)?.length) return null;
168
+
169
+ const loadTable = await getTemplate('table', table);
170
+ if (!pg.pk[loadTable?.table || table]) return null;
171
+ const pk = pg.pk[loadTable?.table || table];
172
+ const id = res.rows?.[0]?.[pk];
173
+
174
+ const { rows: properties = [] } = await pg.query(`select column_id, name, title, format, data from admin.custom_column
175
+ where entity=$1 and uid=$2`, [table, uid]);
176
+
177
+ if (!id || !properties?.length) return null;
178
+
179
+ const q = properties
180
+ .filter((el) => Object.keys(body).includes(el.name))
181
+ .map((el) => `insert into crm.extra_data(property_id,property_key,property_entity,object_id,${el.format?.toLowerCase() === 'date' ? 'value_date' : 'value_text'})
182
+ select '${el.column_id}', '${el.name}', '${table}', '${id}', ${el.format?.toLowerCase() === 'date' ? `'${body[el.name]}'::timestamp without time zone` : `'${body[el.name]}'::text`}`)
183
+ .join(';\n');
184
+ return pg.query(q);
185
+ });
186
186
  }
@@ -1,69 +1,74 @@
1
- import fs from 'fs';
2
- import path, { dirname } from 'path';
3
- import { fileURLToPath } from 'url';
4
-
5
- const dir = dirname(fileURLToPath(import.meta.url));
6
- const root = `${dir}/../..`;
7
-
8
- const isProduction = process.env.NODE_ENV === 'production';
9
-
10
- async function plugin(fastify) {
11
- // vite server
12
- if (!isProduction) {
13
- const vite = await import('vite');
14
-
15
- const viteServer = await vite.createServer({
16
- server: {
17
- middlewareMode: true,
18
- },
19
- });
20
- // hot reload
21
- viteServer.watcher.on('all', function (d, t) {
22
- if (!t.includes('module')) return;
23
- console.log(d, t);
24
- viteServer.ws.send({ type: 'full-reload' });
25
- });
26
-
27
- // this is middleware for vite's dev servert
28
- fastify.addHook('onRequest', async (req, reply) => {
29
- const { user } = req.session?.passport || {};
30
- const { disableAuth } = req.funcs?.config || {};
31
- if (!user && !disableAuth) {
32
- // return reply.send('access restricted');
33
- }
34
-
35
- const next = () => new Promise((resolve) => {
36
- viteServer.middlewares(req.raw, reply.raw, () => resolve());
37
- });
38
- await next();
39
- });
40
- fastify.get('*', async () => { });
41
- return;
42
- }
43
-
44
- // From Build
45
- fastify.get('*', async (req, reply) => {
46
- const { user } = req.session?.passport || {};
47
-
48
- if (!user) return reply.redirect('/login');
49
- const stream = fs.createReadStream('dist/index.html');
50
- return reply.type('text/html').send(stream);
51
- });
52
-
53
- async function staticFile(req, reply) {
54
- const assetsDir = 'dist';
55
- const filePath = path.join(root, assetsDir, req.url);
56
- const ext = path.extname(filePath);
57
- const mime = {
58
- '.js': 'text/javascript', '.css': 'text/css', '.woff2': 'application/font-woff', '.png': 'image/png', '.svg': 'image/svg+xml', '.jpg': 'image/jpg',
59
- }[ext];
60
- reply.headers({ 'Cache-control': 'max-age=3600, public' });
61
- const stream = fs.createReadStream(filePath);
62
- return mime ? reply.type(mime).send(stream) : stream;
63
- }
64
-
65
- fastify.get('/assets/*', staticFile);
66
- fastify.get('/public/*', staticFile);
67
- }
68
-
69
- export default plugin;
1
+ import fs from 'fs';
2
+ import path, { dirname } from 'path';
3
+ import { fileURLToPath } from 'url';
4
+
5
+ const dir = dirname(fileURLToPath(import.meta.url));
6
+ const root = `${dir}/../..`;
7
+
8
+ const isProduction = process.env.NODE_ENV === 'production';
9
+
10
+ async function plugin(fastify) {
11
+ // vite server
12
+ if (!isProduction) {
13
+ const vite = await import('vite');
14
+
15
+ const viteServer = await vite.createServer({
16
+ server: {
17
+ middlewareMode: true,
18
+ },
19
+ });
20
+ // hot reload
21
+ viteServer.watcher.on('all', function (d, t) {
22
+ if (!t.includes('module')) return;
23
+ console.log(d, t);
24
+ viteServer.ws.send({ type: 'full-reload' });
25
+ });
26
+
27
+ // this is middleware for vite's dev servert
28
+ fastify.addHook('onRequest', async (req, reply) => {
29
+ const { user } = req.session?.passport || {};
30
+ const { disableAuth } = req.funcs?.config || {};
31
+ if (!user && !disableAuth) {
32
+ // return reply.send('access restricted');
33
+ }
34
+
35
+ const next = () => new Promise((resolve) => {
36
+ viteServer.middlewares(req.raw, reply.raw, () => resolve());
37
+ });
38
+ await next();
39
+ });
40
+ fastify.get('*', async () => { });
41
+ return;
42
+ }
43
+
44
+ // From Build
45
+ fastify.get('*', async (req, reply) => {
46
+ const { user } = req.session?.passport || {};
47
+
48
+ if (!user) return reply.redirect('/login');
49
+ const stream = fs.createReadStream('dist/index.html');
50
+ return reply.type('text/html').send(stream);
51
+ });
52
+
53
+ const fileSize = {}
54
+ async function staticFile(req, reply) {
55
+ const assetsDir = 'dist';
56
+ const filePath = path.join(root, assetsDir, req.url);
57
+ const ext = path.extname(filePath);
58
+
59
+ if (!fs.existsSync(filePath)) return { status: 404, message: 'not found' }
60
+ fileSize[filePath] = fileSize[filePath] || fs.statSync(filePath).size;
61
+ const mime = {
62
+ '.js': 'text/javascript', '.css': 'text/css', '.woff2': 'application/font-woff', '.png': 'image/png', '.svg': 'image/svg+xml', '.jpg': 'image/jpg',
63
+ }[ext];
64
+ reply.headers({ 'Cache-control': 'max-age=3600, public', 'Content-length': fileSize[filePath], 'Content-Encoding': 'identity' });
65
+
66
+ const stream = fs.createReadStream(filePath);
67
+ return mime ? reply.type(mime).send(stream) : stream;
68
+ }
69
+
70
+ fastify.get('/assets/*', staticFile);
71
+ fastify.get('/public/*', staticFile);
72
+ }
73
+
74
+ export default plugin;