@opengis/admin 0.2.73 → 0.2.75

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengis/admin",
3
- "version": "0.2.73",
3
+ "version": "0.2.75",
4
4
  "description": "This project Softpro Admin",
5
5
  "main": "dist/admin.js",
6
6
  "type": "module",
@@ -26,4 +26,6 @@ export default async function route() {
26
26
  handlebarsSync.registerHelper('ifCond', ifCond);
27
27
  handlebarsSync.registerHelper('button', buttonHelper);
28
28
  handlebars.registerHelper('ifCond', ifCond);
29
+ handlebars.registerHelper('empty', () => { });
30
+ handlebarsSync.registerHelper('empty', () => { });
29
31
  }
@@ -5,8 +5,7 @@ import { fileURLToPath } from 'url';
5
5
  import { createHash } from 'crypto';
6
6
 
7
7
  import {
8
- config, getTemplate, pgClients, handlebars, getFolder, getFilterSQL, logger,
9
- metaFormat,
8
+ config, getTemplate, pgClients, handlebars, getFilterSQL, logger, metaFormat, getMeta,
10
9
  } from '@opengis/fastify-table/utils.js';
11
10
  import { grpc } from '@opengis/fastify-file/utils.js';
12
11
 
@@ -14,6 +13,14 @@ const { htmlToPdf } = grpc();
14
13
  const filename = fileURLToPath(import.meta.url);
15
14
  const dirname = path.dirname(filename);
16
15
 
16
+ // printMap
17
+ const host = 'https://data.gki.com.ua';
18
+ const width = 850;
19
+ const height = 400;
20
+ const geomBuffer = 0.001;
21
+ const layers = '';
22
+ const basemap = 'voyager';
23
+
17
24
  export default async function cardPrint(req, reply) {
18
25
  const { pg = pgClients.client, params = {}, query = {}, user = {} } = req;
19
26
  const { table, id } = params;
@@ -40,6 +47,7 @@ export default async function cardPrint(req, reply) {
40
47
  }
41
48
 
42
49
  const body = await getTemplate('table', table);
50
+ const { geom } = await getMeta({ pg, table: body?.table });
43
51
 
44
52
  if (!body?.table) {
45
53
  return { message: 'table nof found', status: 404 };
@@ -56,7 +64,7 @@ export default async function cardPrint(req, reply) {
56
64
  table,
57
65
  query: where,
58
66
  })
59
- const { rows = [] } = await pg.query(`select * from (${optimizedSQL})q where ${where}`, [id]);
67
+ const { rows = [] } = await pg.query(`select * ${geom ? `, st_asgeojson(${geom})::json as geom` : ''} from (${optimizedSQL})q where ${where}`, [id]);
60
68
 
61
69
  const cls = body?.columns?.filter(el => el.data)?.reduce((acc, curr) => Object.assign(acc, { [curr.name]: curr.data }), {});
62
70
  await metaFormat({ rows, cls, sufix: false });
@@ -66,6 +74,12 @@ export default async function cardPrint(req, reply) {
66
74
  return { message: 'data not found', status: 404 };
67
75
  }
68
76
 
77
+ Object.assign(data, { id: data[body.key || pg.pk?.[body.table]] });
78
+
79
+ const mapUrl = `${host}/api-user/print-map?basemap=${basemap}&layers=${layers || ''}&geojson=${JSON.stringify(data['geom'])}&base64=1&height=${height}&width=${width}&buffer=${geomBuffer}&nocache=1`;
80
+ const resp = data['geom'] ? await fetch(mapUrl) : null;
81
+ const printMap = data['geom'] ? await resp.text() : '';
82
+
69
83
  const pt = await getTemplate('pt', template)
70
84
  || await readFile(path.join(dirname, '../../../templates/pt/card-print.pt.hbs'), 'utf8');
71
85
 
@@ -73,14 +87,17 @@ export default async function cardPrint(req, reply) {
73
87
  const qrCode = `<img src="${await qr.toDataURL(url, { type: 'png', ec_level: 'M', size: 5, margin: 4 })}" alt="qrcode">`;
74
88
 
75
89
  const cardTemplates = await getTemplate('card', table);
76
- const titles = (cardTemplates?.find(el => el[0] === 'index.yml')?.[1] || {})?.panels
77
- ?.reduce((acc, curr) => curr.items?.reduce?.((acc1, curr1) => Object.assign(acc, { [curr1.name]: curr1.title })), {});
90
+ const index = cardTemplates?.find(el => el[0] === 'index.yml')?.[1];
78
91
  const cardHbsTabs = cardTemplates.filter(el => el[0].endsWith('hbs'));
79
92
 
80
- const tabs = tab ? cardHbsTabs.filter(el => [tab, `${tab}.hbs`].includes(el[0])) : cardHbsTabs;
81
- const tabData = await Promise.all(tabs.map(async (el) => {
82
- const html = await handlebars.compile(el[1].replace(/\{\{\{button[^\}]*\}\}\}/g, ''))(data);
83
- return { name: el[0], title: titles[el[0].slice(0, el[0].length - 4)], html };
93
+ const orderedTabs = index?.panels?.flatMap(panel => panel.items?.map(item => {
94
+ const body = cardHbsTabs.find(el => el[0] === `${item.name}.hbs`)?.[1];
95
+ return { ...item, body };
96
+ })).filter(el => el.name && el.body);
97
+
98
+ const tabData = await Promise.all(orderedTabs.map(async (el) => {
99
+ const html = await handlebars.compile(el.body.replace(/\{\{\{button[^\}]*\}\}\}/g, ''))(data);
100
+ return { name: el.name, title: el.title, html };
84
101
  }));
85
102
 
86
103
  const title = data?.[body.meta.title || ''];
@@ -89,6 +106,7 @@ export default async function cardPrint(req, reply) {
89
106
  const obj = {
90
107
  title,
91
108
  table_title: body.ua || body.title,
109
+ printMap,
92
110
  rows: tabData,
93
111
  data: Object.keys(data).filter(el => columnTitles[el]).reduce((acc, curr) => Object.assign(acc, { [columnTitles[curr] || curr]: data[curr] }), {}),
94
112
  rawData: data,
@@ -108,6 +126,6 @@ export default async function cardPrint(req, reply) {
108
126
  // await mkdir(path.dirname(filepath), { recursive: true });
109
127
  // await writeFile(filepath, buffer);
110
128
 
111
- logger.file('printPdf', { table, id, format, uid: user?.uid });
129
+ logger.file('cardPrint', { table, id, format, uid: user?.uid });
112
130
  return reply.headers(headers).send(buffer);
113
131
  }
@@ -1,15 +1,217 @@
1
- <h2>{{table_title}}</h2>
1
+ <div style="display:flex; flex-direction: row; align-items: start; justify-content:space-between">
2
+ <div
3
+ style=" display: flex; flex-direction:column; text-align: center; align-items: center; justify-content: center; width:100%;">
4
+ {{#if table_title}}<h2 style="text-align: center;">{{table_title}}</h2>{{/if}}
5
+ {{#if title}}<h3>{{title}}</h3>{{/if}}
6
+ <p>{{formatDate 0 format="dd.mm.yy / hh:mi"}}</p>
7
+ </div>
8
+ <div class="qr-wrapper" style=" width:180px; height:180px;">{{{qr}}}</div>
9
+ </div>
2
10
 
3
- <h3>{{title}}</h3>
11
+ <div class="print-map">
12
+ {{{printMap}}}
13
+ </div>
4
14
 
5
- <hr>
6
- {{{json data}}}
7
- <hr>
8
15
  {{#each rows}}
9
- <h3>{{title}}</h3>
10
- <div>{{{html}}}</div>
16
+ <div style="margin-bottom:30px">
17
+ <h3>{{title}}</h3>
18
+ <div>{{{html}}}</div>
19
+ </div>
20
+
11
21
  {{/each}}
12
- <hr>
13
- {{{url}}}
14
- <hr>
15
- {{{qr}}}
22
+ <div style="margin-top: 50px;">
23
+ <hr />
24
+ <div style="word-break: break-all;">{{{url}}}</div>
25
+
26
+ </div>
27
+
28
+ <style>
29
+ * {
30
+ margin: 0;
31
+ padding: 0;
32
+ box-sizing: border-box;
33
+ }
34
+
35
+ body {
36
+ font-family:
37
+ Arial, sans-serif;
38
+ font-size: 14px;
39
+ color: #333;
40
+ line-height: 1.5;
41
+ background-color: #fff;
42
+ }
43
+
44
+ h1,
45
+ h2,
46
+ h3 {
47
+ font-weight: bold;
48
+ margin-bottom: 15px;
49
+ color: #000;
50
+ }
51
+
52
+ h2 {
53
+ font-size: 28px;
54
+ margin-bottom: 10px;
55
+ }
56
+
57
+ h3 {
58
+ font-size:
59
+ 18px;
60
+ margin-bottom: 10px;
61
+ }
62
+
63
+ div.font-semibold {
64
+ margin-bottom: 15px;
65
+ color:
66
+ #000000;
67
+ font-size: 16px;
68
+ }
69
+
70
+ hr {
71
+ border: none;
72
+ border-top: 1px solid #ddd;
73
+ margin: 15px 0;
74
+ }
75
+
76
+ dl {
77
+ margin: 10px 0 25px;
78
+ width: 100%;
79
+ }
80
+
81
+ dl>div {
82
+ display:
83
+ flex;
84
+ flex-wrap: wrap;
85
+ align-items: center;
86
+ padding: 10px 0;
87
+ border-bottom:
88
+ 1px solid #ddd;
89
+ }
90
+
91
+ dt {
92
+ font-weight: 400;
93
+ color: #111827;
94
+ width: 50%;
95
+ min-width: 150px;
96
+ padding-right: 10px;
97
+ }
98
+
99
+ dd {
100
+ flex: 1;
101
+ color: #374151;
102
+ }
103
+
104
+ div.bg-gray-200.text-center.p-6.rounded-xl h3 {
105
+ color: #374151;
106
+ font-weight: 400;
107
+ font-size: 14px;
108
+ }
109
+
110
+ button {
111
+ display: none;
112
+ }
113
+
114
+ a {
115
+ color: #374151;
116
+ text-decoration: none;
117
+ transition: color 0.3s;
118
+ }
119
+
120
+ ul {
121
+ list-style: none;
122
+ margin: 10px 0;
123
+ padding-left:
124
+ 20px;
125
+ }
126
+
127
+ li {
128
+ margin-bottom: 5px;
129
+ color: #374151;
130
+ font-size: 16px;
131
+ }
132
+
133
+ button {
134
+ padding: 8px 12px;
135
+ font-size: 14px;
136
+ font-weight: 600;
137
+ border: none;
138
+ border-radius: 4px;
139
+ }
140
+
141
+ .qr-wrapper img {
142
+ width: 100%;
143
+ object-fit: cover;
144
+ }
145
+
146
+ .text-sm {
147
+ font-size: 14px;
148
+ }
149
+
150
+ .text-gray-700 {
151
+ color:
152
+ #4a5568;
153
+ }
154
+
155
+ .text-gray-900 {
156
+ color: #1a202c;
157
+ }
158
+
159
+ .font-semibold {
160
+ font-weight:
161
+ 600;
162
+ }
163
+
164
+ .rounded-md {
165
+ border-radius: 6px;
166
+ }
167
+
168
+ .gap-4 {
169
+ gap: 16px;
170
+ }
171
+
172
+ .grid {
173
+ display: grid;
174
+ gap: 16px;
175
+ }
176
+
177
+ .grid-cols-1 {
178
+ grid-template-columns: 1fr;
179
+ }
180
+
181
+ .sm\\:grid-cols-3 {
182
+ grid-template-columns: repeat(3, 1fr);
183
+ }
184
+
185
+ .sm\\:col-span-2 {
186
+ grid-column: span 2 / span 2;
187
+ }
188
+
189
+ .divide-y>div:not(:last-child) {
190
+ border-bottom: 1px solid #ddd;
191
+ }
192
+
193
+ .flex {
194
+ display: flex;
195
+ align-items: center;
196
+ }
197
+
198
+ .justify-between {
199
+ justify-content: space-between;
200
+ }
201
+
202
+ .justify-center {
203
+ justify-content: center;
204
+ }
205
+
206
+ .border-b {
207
+ border-bottom: 1px solid #ddd;
208
+ }
209
+
210
+ .pb-\\[15px\\] {
211
+ padding-bottom: 15px;
212
+ }
213
+
214
+ .pt-\\[30px\\] {
215
+ padding-top: 30px;
216
+ }
217
+ </style>