@opengis/bi 1.2.31 → 1.2.34
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/dist/bi.js +1 -1
- package/dist/bi.umd.cjs +84 -82
- package/dist/{import-file-BPICIF0w.js → import-file-BwxPX622.js} +2321 -2089
- package/dist/style.css +1 -1
- package/dist/{vs-funnel-bar-C4T5wkBI.js → vs-funnel-bar-BV18EA4K.js} +1 -1
- package/dist/{vs-list-DpQecJFZ.js → vs-list-WrrWQ5KF.js} +1 -1
- package/dist/{vs-map-Dv0Zxj3b.js → vs-map-CYd9vdrd.js} +102 -91
- package/dist/{vs-map-cluster-BZoSRi6v.js → vs-map-cluster-5TnGPuBH.js} +91 -81
- package/dist/{vs-number-CRdeu_TC.js → vs-number-DUeRr7uz.js} +1 -1
- package/dist/{vs-table-BMs9Rxrh.js → vs-table-CZJnXfUv.js} +1 -1
- package/dist/{vs-text-B46_k-vY.js → vs-text-D3nCPkgk.js} +1 -1
- package/package.json +19 -17
- package/plugin.js +6 -7
- package/server/migrations/bi.sql +4 -1
- package/server/plugins/hook.js +5 -5
- package/server/plugins/vite.js +81 -81
- package/server/routes/dashboard/controllers/dashboard.js +3 -2
- package/server/routes/dashboard/controllers/dashboard.list.js +1 -1
- package/server/routes/data/controllers/data.js +1 -0
- package/server/utils/getWidget.js +6 -5
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { _ as
|
|
2
|
-
import { e as
|
|
3
|
-
import { createElementBlock as
|
|
1
|
+
import { _ as O, a as A, p as T, c as F, V as P, b as G, d as W, e as Z, l as q } from "./vs-list-WrrWQ5KF.js";
|
|
2
|
+
import { e as K, _ as H, V as J, c as Q, g as U, h as X, i as Y } from "./import-file-BwxPX622.js";
|
|
3
|
+
import { createElementBlock as x, createCommentVNode as S, openBlock as p, createElementVNode as l, normalizeClass as C, Fragment as D, renderList as R, toDisplayString as N, normalizeStyle as $, createBlock as z, unref as j, mergeProps as ee, resolveComponent as v, withDirectives as M, resolveDynamicComponent as te, createVNode as w, vShow as I } from "vue";
|
|
4
4
|
/**
|
|
5
5
|
* @license lucide-vue-next v0.577.0 - ISC
|
|
6
6
|
*
|
|
7
7
|
* This source code is licensed under the ISC license.
|
|
8
8
|
* See the LICENSE file in the root directory of this source tree.
|
|
9
9
|
*/
|
|
10
|
-
const se =
|
|
10
|
+
const se = K("map", [
|
|
11
11
|
[
|
|
12
12
|
"path",
|
|
13
13
|
{
|
|
@@ -18,7 +18,7 @@ const se = W("map", [
|
|
|
18
18
|
["path", { d: "M15 5.764v15", key: "1pn4in" }],
|
|
19
19
|
["path", { d: "M9 3.236v15", key: "1uimfh" }]
|
|
20
20
|
]), oe = {
|
|
21
|
-
components: { legendIcon:
|
|
21
|
+
components: { legendIcon: A, closeIcon: O },
|
|
22
22
|
props: {
|
|
23
23
|
mapId: { type: String },
|
|
24
24
|
colors: { type: Array },
|
|
@@ -42,11 +42,11 @@ const se = W("map", [
|
|
|
42
42
|
return this.cluster ? "rounded-sm" : "rounded-full";
|
|
43
43
|
},
|
|
44
44
|
sortedSizes() {
|
|
45
|
-
return [...this.sizes].sort((t,
|
|
45
|
+
return [...this.sizes].sort((t, a) => t - a);
|
|
46
46
|
},
|
|
47
47
|
maxWidht() {
|
|
48
|
-
var
|
|
49
|
-
const t = ((
|
|
48
|
+
var r;
|
|
49
|
+
const t = ((r = this.sizes) == null ? void 0 : r.length) - 1;
|
|
50
50
|
return this.calcSize(t);
|
|
51
51
|
}
|
|
52
52
|
},
|
|
@@ -65,26 +65,26 @@ const se = W("map", [
|
|
|
65
65
|
key: 0,
|
|
66
66
|
class: "absolute flex items-end w-fit bottom-[10px] max-w-[80%] left-[50%] translate-x-[-50%] bg-[rgba(255,255,255,0.7)] p-[10px] rounded"
|
|
67
67
|
}, re = { class: "w-[80px] mr-[10px]" }, ie = ["title"], ne = { class: "text-[10px] mb-[2px] text-[#1F2937] font-normal leading-[1.2]" };
|
|
68
|
-
function le(t,
|
|
69
|
-
var
|
|
70
|
-
return (
|
|
68
|
+
function le(t, a, r, o, e, s) {
|
|
69
|
+
var g;
|
|
70
|
+
return (g = r.sizes) != null && g.length ? (p(), x("div", ae, [
|
|
71
71
|
l("div", re, [
|
|
72
|
-
|
|
72
|
+
a[0] || (a[0] = l("p", { class: "text-[10px] mb-[2px] text-[#1F2937] leading-[1.2]" }, " Дані відсутні ", -1)),
|
|
73
73
|
l("div", {
|
|
74
|
-
class:
|
|
74
|
+
class: C([s.sizeClass(t.index), "w-full border border-gray-500"])
|
|
75
75
|
}, null, 2)
|
|
76
76
|
]),
|
|
77
|
-
|
|
78
|
-
var
|
|
79
|
-
return p(),
|
|
77
|
+
s.sortedSizes.length ? (p(!0), x(D, { key: 0 }, R(s.sortedSizes, (c, n) => {
|
|
78
|
+
var y, f, b, d, _, h, u, m;
|
|
79
|
+
return p(), x("div", {
|
|
80
80
|
class: "w-[80px]",
|
|
81
|
-
title: n === ((
|
|
81
|
+
title: n === ((y = s.sortedSizes) == null ? void 0 : y.length) - 1 ? ">" + c : n == ((f = s.sortedSizes) == null ? void 0 : f.length) - 1 ? ">" + s.sortedSizes[((b = s.sortedSizes) == null ? void 0 : b.length) - 1] : c + "-" + s.sortedSizes[n + 1]
|
|
82
82
|
}, [
|
|
83
|
-
l("p", ne,
|
|
83
|
+
l("p", ne, N(n === ((d = s.sortedSizes) == null ? void 0 : d.length) - 1 ? ">" + parseInt(c) : n == ((_ = s.sortedSizes) == null ? void 0 : _.length) - 1 ? ">" + parseInt(s.sortedSizes[((h = s.sortedSizes) == null ? void 0 : h.length) - 1]) : parseInt(c) + "-" + parseInt(s.sortedSizes[n + 1])), 1),
|
|
84
84
|
l("div", {
|
|
85
|
-
class:
|
|
86
|
-
style:
|
|
87
|
-
backgroundColor: ((
|
|
85
|
+
class: C([s.sizeClass(n), "w-full border border-r-0 border-gray-500"]),
|
|
86
|
+
style: $({
|
|
87
|
+
backgroundColor: ((m = (u = e.palette) == null ? void 0 : u[r.color]) == null ? void 0 : m[n]) || r.color
|
|
88
88
|
})
|
|
89
89
|
}, null, 6)
|
|
90
90
|
], 8, ie);
|
|
@@ -94,16 +94,16 @@ function le(t, s, o, a, e, r) {
|
|
|
94
94
|
const pe = /* @__PURE__ */ H(oe, [["render", le]]), ce = {
|
|
95
95
|
__name: "icon-map",
|
|
96
96
|
setup(t) {
|
|
97
|
-
return (
|
|
97
|
+
return (a, r) => (p(), z(j(se), ee(a.$attrs, { size: 24 }), null, 16));
|
|
98
98
|
}
|
|
99
99
|
}, de = {
|
|
100
|
-
mixins: [Q,
|
|
100
|
+
mixins: [Q, Z],
|
|
101
101
|
components: {
|
|
102
|
-
VsMapSetting:
|
|
102
|
+
VsMapSetting: W,
|
|
103
103
|
VsClusterLegend: pe,
|
|
104
|
-
VsMapGoHome:
|
|
104
|
+
VsMapGoHome: G,
|
|
105
105
|
VsList: P,
|
|
106
|
-
VsMapSlotLayers:
|
|
106
|
+
VsMapSlotLayers: F,
|
|
107
107
|
// VsListbar,
|
|
108
108
|
VsBar: J
|
|
109
109
|
},
|
|
@@ -139,52 +139,62 @@ const pe = /* @__PURE__ */ H(oe, [["render", le]]), ce = {
|
|
|
139
139
|
},
|
|
140
140
|
methods: {
|
|
141
141
|
async getMapData() {
|
|
142
|
-
|
|
143
|
-
|
|
142
|
+
var o, e;
|
|
143
|
+
if (this.prefetchedData) {
|
|
144
|
+
this.data = this.prefetchedData, this.$emit("update:widgetData", this.data), setTimeout(() => {
|
|
145
|
+
var s;
|
|
146
|
+
return (s = this.map) == null ? void 0 : s.resize();
|
|
147
|
+
});
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
const t = ((o = this.resolveWidgetId) == null ? void 0 : o.call(this)) || this.widget, a = ((e = this.resolveDashboardId) == null ? void 0 : e.call(this)) || this.dashboard, r = await U.get(
|
|
151
|
+
`/bi-cluster?widget=${t}&dashboard=${a}`
|
|
144
152
|
);
|
|
145
|
-
this.data =
|
|
153
|
+
this.data = r, this.$emit("update:widgetData", this.data), setTimeout(() => {
|
|
146
154
|
var s;
|
|
147
155
|
return (s = this.map) == null ? void 0 : s.resize();
|
|
148
156
|
});
|
|
149
157
|
},
|
|
150
158
|
async loadHandler() {
|
|
151
|
-
var
|
|
152
|
-
this.baseColor = ((
|
|
159
|
+
var g, c, n, y, f, b, d;
|
|
160
|
+
this.baseColor = ((g = this.data.style) == null ? void 0 : g.color) || "blue";
|
|
153
161
|
const t = ["case"];
|
|
154
|
-
(
|
|
155
|
-
var
|
|
156
|
-
t.push([">", ["get", "metric"],
|
|
162
|
+
(y = (n = (c = this.data) == null ? void 0 : c.sizes) == null ? void 0 : n.toReversed()) == null || y.forEach((_, h) => {
|
|
163
|
+
var u, m;
|
|
164
|
+
t.push([">", ["get", "metric"], _]), t.push((m = (u = T[this.baseColor]) == null ? void 0 : u.toReversed()) == null ? void 0 : m[h]), h++;
|
|
157
165
|
}), t.push("gray");
|
|
158
|
-
const
|
|
166
|
+
const a = {
|
|
159
167
|
type: "polygon",
|
|
160
168
|
color: t,
|
|
161
169
|
opacity: 0.4
|
|
162
170
|
};
|
|
163
|
-
Object.assign(
|
|
171
|
+
Object.assign(a, this.data.style || {});
|
|
172
|
+
const r = ((f = this.resolveWidgetId) == null ? void 0 : f.call(this)) || this.widget, o = ((b = this.resolveDashboardId) == null ? void 0 : b.call(this)) || this.dashboard, e = ((d = this.resolvePrefix) == null ? void 0 : d.call(this)) || "/api";
|
|
173
|
+
this.map.getSource("bi") || this.addVtileLayer({
|
|
164
174
|
id: "bi",
|
|
165
|
-
url: `${window.location.origin}/
|
|
166
|
-
style:
|
|
175
|
+
url: `${window.location.origin}${e}/bi-cluster-vtile/{z}/{x}/{y}.vmt?widget=${r}&dashboard=${o}&nocache=1`,
|
|
176
|
+
style: a
|
|
167
177
|
}), this.map.getLayer("highlighted") && this.map.removeLayer("highlighted"), this.map.getSource("highlighted") && this.map.removeSource("highlighted");
|
|
168
|
-
const
|
|
169
|
-
this.kattotg &&
|
|
178
|
+
const s = ["case"];
|
|
179
|
+
this.kattotg && s.push(
|
|
170
180
|
["==", ["to-string", ["get", "name"]], String(this.kattotg)],
|
|
171
181
|
"red"
|
|
172
|
-
),
|
|
182
|
+
), s.push("transparent"), this.map.addLayer({
|
|
173
183
|
id: "highlighted",
|
|
174
184
|
type: "fill",
|
|
175
185
|
source: "bi",
|
|
176
186
|
"source-layer": "bi",
|
|
177
187
|
paint: {
|
|
178
|
-
"fill-color":
|
|
188
|
+
"fill-color": s,
|
|
179
189
|
"fill-opacity": 0.6
|
|
180
190
|
}
|
|
181
191
|
});
|
|
182
192
|
},
|
|
183
193
|
async createMap() {
|
|
184
|
-
var
|
|
185
|
-
const t = await
|
|
194
|
+
var r, o;
|
|
195
|
+
const t = await q();
|
|
186
196
|
if (!t) return;
|
|
187
|
-
const
|
|
197
|
+
const a = {
|
|
188
198
|
version: 8,
|
|
189
199
|
glyphs: "https://cdn.softpro.ua/data/fonts/{fontstack}/{range}.pbf",
|
|
190
200
|
sources: {},
|
|
@@ -192,9 +202,9 @@ const pe = /* @__PURE__ */ H(oe, [["render", le]]), ce = {
|
|
|
192
202
|
};
|
|
193
203
|
this.map = await new t.Map({
|
|
194
204
|
container: this.mapId,
|
|
195
|
-
style:
|
|
205
|
+
style: a,
|
|
196
206
|
center: [31, 48.5],
|
|
197
|
-
zoom: ((
|
|
207
|
+
zoom: ((o = (r = this.data) == null ? void 0 : r.style) == null ? void 0 : o.zoom) || 5,
|
|
198
208
|
minZoom: 3,
|
|
199
209
|
maxZoom: 20,
|
|
200
210
|
attributionControl: !1
|
|
@@ -212,40 +222,40 @@ const pe = /* @__PURE__ */ H(oe, [["render", le]]), ce = {
|
|
|
212
222
|
});
|
|
213
223
|
},
|
|
214
224
|
moveMouseHadler(t) {
|
|
215
|
-
var
|
|
225
|
+
var a;
|
|
216
226
|
try {
|
|
217
|
-
const
|
|
218
|
-
if (!
|
|
227
|
+
const r = this.map.queryRenderedFeatures(t.point), o = ((a = r[0]) == null ? void 0 : a.properties) || {};
|
|
228
|
+
if (!r.length) {
|
|
219
229
|
this.map.getCanvas().style.cursor = "", this.popupElement && this.popupElement.remove();
|
|
220
230
|
return;
|
|
221
231
|
}
|
|
222
232
|
this.map.getCanvas().style.cursor = "pointer", this.popupElement && this.popupElement.remove(), this.popupElement = document.createElement("div"), this.popupElement.className = "absolute text-gray-800 border border-gray-200 rounded-lg shadow-md min-w-28", this.popupElement.style.backgroundColor = "rgba(255, 255, 255, 0.7)", this.popupElement.innerHTML = `<div class="px-2 py-1 text-sm font-semibold text-gray-800 border-b border-gray-200 border-solid rounded-t-lg">
|
|
223
|
-
${(
|
|
233
|
+
${(o == null ? void 0 : o.x) || (o == null ? void 0 : o.title) || (o == null ? void 0 : o.name) || ""}
|
|
224
234
|
</div>
|
|
225
235
|
|
|
226
236
|
<div class="flex justify-between items-center text-xs px-2 py-0.5 text-gray-500 ">
|
|
227
237
|
<span class="flex items-center">
|
|
228
238
|
<span class="font-medium mr-[6px]">Значення</span>
|
|
229
239
|
</span>
|
|
230
|
-
<span>${(
|
|
240
|
+
<span>${(o == null ? void 0 : o.metric) || 0}</span>
|
|
231
241
|
</div>`;
|
|
232
242
|
const e = this.map.project(t.lngLat);
|
|
233
243
|
this.popupElement.style.left = `${e.x}px`, this.popupElement.style.top = `${e.y - 60}px`, this.map.getContainer().appendChild(this.popupElement);
|
|
234
|
-
} catch (
|
|
235
|
-
console.error(
|
|
244
|
+
} catch (r) {
|
|
245
|
+
console.error(r);
|
|
236
246
|
}
|
|
237
247
|
}
|
|
238
248
|
}
|
|
239
|
-
}, he = { class: "h-full" }, ue = { class: "flex items-start justify-between mb-[6px] w-full" }, me = { class: "text-gray-800 font-[600]" }, ge = { class: "flex gap-2" }, ye = ["onClick"], fe = ["id"],
|
|
240
|
-
function
|
|
241
|
-
var
|
|
242
|
-
const
|
|
243
|
-
return p(),
|
|
249
|
+
}, he = { class: "h-full" }, ue = { class: "flex items-start justify-between mb-[6px] w-full" }, me = { class: "text-gray-800 font-[600]" }, ge = { class: "flex gap-2" }, ye = ["onClick"], fe = ["id"], be = ["id"], _e = { class: "absolute flex flex-col right-[10px] top-[105px] gap-1" }, ve = { class: "h-[calc(250px)]" };
|
|
250
|
+
function xe(t, a, r, o, e, s) {
|
|
251
|
+
var d, _, h, u, m, V, k, L, E, B;
|
|
252
|
+
const g = v("VsMapSetting"), c = v("VsMapSlotLayers"), n = v("VsMapGoHome"), y = v("VsClusterLegend"), f = v("VsList"), b = v("VsBar");
|
|
253
|
+
return p(), x("div", he, [
|
|
244
254
|
l("div", ue, [
|
|
245
|
-
l("h3", me,
|
|
255
|
+
l("h3", me, N(t.title), 1),
|
|
246
256
|
l("div", ge, [
|
|
247
|
-
(p(!0),
|
|
248
|
-
class:
|
|
257
|
+
(p(!0), x(D, null, R(e.options, (i) => (p(), x("button", {
|
|
258
|
+
class: C(["p-1 text-gray-700 border rounded", [e.activeTab === (i == null ? void 0 : i.id) ? "ring-2 ring-blue-500" : ""]]),
|
|
249
259
|
onClick: (we) => e.activeTab = i == null ? void 0 : i.id
|
|
250
260
|
}, [
|
|
251
261
|
(p(), z(te(i == null ? void 0 : i.component), {
|
|
@@ -262,41 +272,41 @@ function ve(t, s, o, a, e, r) {
|
|
|
262
272
|
l("div", {
|
|
263
273
|
id: e.mapId,
|
|
264
274
|
class: "h-full w-full flex items-end min-h-[250px]"
|
|
265
|
-
}, null, 8,
|
|
266
|
-
e.showSetting ? (p(), z(
|
|
275
|
+
}, null, 8, be),
|
|
276
|
+
e.showSetting ? (p(), z(g, {
|
|
267
277
|
key: 0,
|
|
268
278
|
map: e.map,
|
|
269
279
|
coordinates: e.coordinatesByMouse
|
|
270
280
|
}, null, 8, ["map", "coordinates"])) : S("", !0),
|
|
271
281
|
w(c, { map: e.map }, null, 8, ["map"]),
|
|
272
|
-
l("div",
|
|
282
|
+
l("div", _e, [
|
|
273
283
|
w(n, {
|
|
274
284
|
map: e.map,
|
|
275
|
-
bbox: (
|
|
285
|
+
bbox: (d = e.data) == null ? void 0 : d.bounds
|
|
276
286
|
}, null, 8, ["map", "bbox"])
|
|
277
287
|
]),
|
|
278
|
-
w(
|
|
288
|
+
w(y, {
|
|
279
289
|
mapId: e.mapId,
|
|
280
|
-
colors: (
|
|
281
|
-
sizes: (
|
|
290
|
+
colors: (_ = e.data) == null ? void 0 : _.colors,
|
|
291
|
+
sizes: (h = e.data) == null ? void 0 : h.sizes,
|
|
282
292
|
color: e.baseColor,
|
|
283
293
|
changeOpacityItem: "true",
|
|
284
294
|
cluster: "true"
|
|
285
295
|
}, null, 8, ["mapId", "colors", "sizes", "color"])
|
|
286
296
|
], 8, fe), [
|
|
287
|
-
[
|
|
297
|
+
[I, e.activeTab == "map"]
|
|
288
298
|
]),
|
|
289
|
-
M(w(
|
|
299
|
+
M(w(f, {
|
|
290
300
|
mapId: e.mapId,
|
|
291
|
-
source: (
|
|
292
|
-
total: ((
|
|
293
|
-
count: ((
|
|
294
|
-
onKattotg:
|
|
301
|
+
source: (u = e.data) == null ? void 0 : u.rows,
|
|
302
|
+
total: ((m = e.data) == null ? void 0 : m.total) || 0,
|
|
303
|
+
count: ((V = e.data) == null ? void 0 : V.count) || 0,
|
|
304
|
+
onKattotg: a[0] || (a[0] = (i) => e.kattotg = i)
|
|
295
305
|
}, null, 8, ["mapId", "source", "total", "count"]), [
|
|
296
|
-
[
|
|
306
|
+
[I, e.activeTab == "table"]
|
|
297
307
|
]),
|
|
298
|
-
M(l("div",
|
|
299
|
-
(L = (k = e.data) == null ? void 0 : k.rows) != null && L.length ? (p(), z(
|
|
308
|
+
M(l("div", ve, [
|
|
309
|
+
(L = (k = e.data) == null ? void 0 : k.rows) != null && L.length ? (p(), z(b, {
|
|
300
310
|
key: 0,
|
|
301
311
|
source: (B = (E = e.data) == null ? void 0 : E.rows) == null ? void 0 : B.map((i) => ({
|
|
302
312
|
title: i == null ? void 0 : i.title,
|
|
@@ -304,11 +314,11 @@ function ve(t, s, o, a, e, r) {
|
|
|
304
314
|
}))
|
|
305
315
|
}, null, 8, ["source"])) : S("", !0)
|
|
306
316
|
], 512), [
|
|
307
|
-
[
|
|
317
|
+
[I, e.activeTab == "chart"]
|
|
308
318
|
])
|
|
309
319
|
]);
|
|
310
320
|
}
|
|
311
|
-
const
|
|
321
|
+
const Ie = /* @__PURE__ */ H(de, [["render", xe]]);
|
|
312
322
|
export {
|
|
313
|
-
|
|
323
|
+
Ie as default
|
|
314
324
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _ as m, c as f, b as _, d as b } from "./import-file-
|
|
1
|
+
import { _ as m, c as f, b as _, d as b } from "./import-file-BwxPX622.js";
|
|
2
2
|
import { createElementBlock as a, openBlock as r, createElementVNode as s, Fragment as n, renderList as c, toDisplayString as d } from "vue";
|
|
3
3
|
const x = {
|
|
4
4
|
name: "VsTable",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengis/bi",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.34",
|
|
4
4
|
"description": "BI data visualization module",
|
|
5
5
|
"main": "dist/bi.js",
|
|
6
6
|
"browser": "dist/bi.umd.cjs",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"format": "prettier --write .",
|
|
25
25
|
"test": "node --test",
|
|
26
26
|
"test21": "node --test ./test/plugins/*",
|
|
27
|
-
"start": "
|
|
27
|
+
"start": "bun --env-file=.env.bi server.js",
|
|
28
28
|
"prod": "NODE_ENV=production npm run start",
|
|
29
29
|
"docs:i": "npm install --prefix ./docs",
|
|
30
30
|
"docs:dev": "npm run --prefix ./docs docs:dev",
|
|
@@ -47,29 +47,31 @@
|
|
|
47
47
|
"@opengis/table": "^0.0.30",
|
|
48
48
|
"lucide-vue-next": "^0.577.0"
|
|
49
49
|
},
|
|
50
|
+
"peerDependencies": {
|
|
51
|
+
"@opengis/fastify-table": "^2.1.3"
|
|
52
|
+
},
|
|
50
53
|
"devDependencies": {
|
|
51
54
|
"@opengis/core": "^0.0.33",
|
|
52
|
-
"@opengis/fastify-table": "^2.0.33",
|
|
53
55
|
"@opengis/form": "0.0.137",
|
|
54
|
-
"@turf/turf": "^7.
|
|
55
|
-
"@types/node": "^22.
|
|
56
|
+
"@turf/turf": "^7.3.4",
|
|
57
|
+
"@types/node": "^22.19.17",
|
|
56
58
|
"@typescript-eslint/eslint-plugin": "^6.21.0",
|
|
57
59
|
"@typescript-eslint/parser": "^6.21.0",
|
|
58
|
-
"@vitejs/plugin-vue": "^5.
|
|
60
|
+
"@vitejs/plugin-vue": "^5.2.4",
|
|
59
61
|
"cross-env": "^10.1.0",
|
|
60
62
|
"eslint": "^8.57.1",
|
|
61
63
|
"eslint-config-airbnb-base": "^15.0.0",
|
|
62
|
-
"eslint-config-prettier": "^9.1.
|
|
63
|
-
"eslint-plugin-vue": "^9.
|
|
64
|
-
"globals": "^15.
|
|
65
|
-
"marked": "^14.1.
|
|
66
|
-
"prettier": "^3.
|
|
67
|
-
"rollup-plugin-visualizer": "^7.0.
|
|
64
|
+
"eslint-config-prettier": "^9.1.2",
|
|
65
|
+
"eslint-plugin-vue": "^9.33.0",
|
|
66
|
+
"globals": "^15.15.0",
|
|
67
|
+
"marked": "^14.1.4",
|
|
68
|
+
"prettier": "^3.8.1",
|
|
69
|
+
"rollup-plugin-visualizer": "^7.0.1",
|
|
68
70
|
"sass-embedded": "1.89.2",
|
|
69
|
-
"typescript": "^5.
|
|
70
|
-
"vite": "^5.
|
|
71
|
-
"vue": "^3.
|
|
72
|
-
"vue-router": "^4.4
|
|
73
|
-
"vue-tsc": "^2.
|
|
71
|
+
"typescript": "^5.9.3",
|
|
72
|
+
"vite": "^5.4.21",
|
|
73
|
+
"vue": "^3.5.32",
|
|
74
|
+
"vue-router": "^4.6.4",
|
|
75
|
+
"vue-tsc": "^2.2.12"
|
|
74
76
|
}
|
|
75
77
|
}
|
package/plugin.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import fp from 'fastify-plugin';
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
import { /*config, addTemplateDir,*/ pgClients, execMigrations } from '@opengis/fastify-table/utils.js';
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
// const dirName = path.dirname(fileName);
|
|
7
|
+
const dirName = path.dirname(fileURLToPath(import.meta.url));
|
|
9
8
|
|
|
10
9
|
async function plugin(fastify, opt) {
|
|
11
10
|
fastify.register(import('./server/routes/dashboard/index.mjs'), opt);
|
|
@@ -16,7 +15,7 @@ async function plugin(fastify, opt) {
|
|
|
16
15
|
fastify.register(import('./server/routes/map/index.mjs'), opt);
|
|
17
16
|
// config.templates?.forEach(el => addTemplateDir(el));
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
const dir = path.join(dirName, 'server/migrations');
|
|
19
|
+
execMigrations(dir, pgClients.client).catch(err => console.log(err));
|
|
21
20
|
}
|
|
22
21
|
export default fp(plugin);
|
package/server/migrations/bi.sql
CHANGED
|
@@ -109,4 +109,7 @@ ALTER TABLE bi.cluster ADD CONSTRAINT bi_cluster_title_type_unique UNIQUE(title,
|
|
|
109
109
|
comment on table bi.cluster is 'Дані для побудови cluster віджетів';
|
|
110
110
|
|
|
111
111
|
comment on column bi.cluster.title is 'Назва';
|
|
112
|
-
comment on column bi.cluster.type is 'Тип кластеру';
|
|
112
|
+
comment on column bi.cluster.type is 'Тип кластеру';
|
|
113
|
+
|
|
114
|
+
alter table bi.dashboard add column if not exists updated_at timestamp without time zone NOT NULL DEFAULT date_trunc('seconds'::text, now());
|
|
115
|
+
alter table bi.widget add column if not exists updated_at timestamp without time zone NOT NULL DEFAULT date_trunc('seconds'::text, now());
|
package/server/plugins/hook.js
CHANGED
|
@@ -62,11 +62,11 @@ async function plugin(fastify) {
|
|
|
62
62
|
});
|
|
63
63
|
|
|
64
64
|
// allow upload file
|
|
65
|
-
const kIsMultipart = Symbol.for('[FastifyMultipart.isMultipart]');
|
|
66
|
-
fastify.addContentTypeParser('multipart', (request, _, done) => {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
});
|
|
65
|
+
// const kIsMultipart = Symbol.for('[FastifyMultipart.isMultipart]');
|
|
66
|
+
// fastify.addContentTypeParser('multipart', (request, _, done) => {
|
|
67
|
+
// request[kIsMultipart] = true;
|
|
68
|
+
// done(null);
|
|
69
|
+
// });
|
|
70
70
|
|
|
71
71
|
// parse Body
|
|
72
72
|
function contentParser(req, body, done) {
|
package/server/plugins/vite.js
CHANGED
|
@@ -1,81 +1,81 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import { fileURLToPath } from 'url';
|
|
4
|
-
import config from '../../config.js';
|
|
5
|
-
|
|
6
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
7
|
-
const rootDir = path.resolve(__dirname, '../..');
|
|
8
|
-
const distIndexPath = path.join(rootDir, 'dist', 'index.html');
|
|
9
|
-
const distAssetsDir = path.join(rootDir, 'dist', 'assets');
|
|
10
|
-
|
|
11
|
-
const { disableAuth } = config;
|
|
12
|
-
const isProduction = process.env.NODE_ENV === 'production';
|
|
13
|
-
|
|
14
|
-
async function plugin(fastify) {
|
|
15
|
-
// vite server
|
|
16
|
-
if (!isProduction) {
|
|
17
|
-
const vite = await import('vite');
|
|
18
|
-
|
|
19
|
-
const viteServer = await vite.createServer({
|
|
20
|
-
server: {
|
|
21
|
-
middlewareMode: true,
|
|
22
|
-
},
|
|
23
|
-
});
|
|
24
|
-
// hot reload
|
|
25
|
-
viteServer.watcher.on('all', (d, t) => {
|
|
26
|
-
if (!t.includes('module') && !t.includes('templates')) return;
|
|
27
|
-
// console.log(d, t);
|
|
28
|
-
viteServer.ws.send({ type: 'full-reload' });
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
// this is middleware for vite's dev servert
|
|
32
|
-
fastify.addHook('onRequest', async (req, reply) => {
|
|
33
|
-
// const { user } = req.session?.passport || {};
|
|
34
|
-
const next = () => new Promise((resolve) => {
|
|
35
|
-
viteServer.middlewares(req.raw, reply.raw, () => resolve());
|
|
36
|
-
});
|
|
37
|
-
await next();
|
|
38
|
-
});
|
|
39
|
-
fastify.get('*', async () => {});
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// From Build
|
|
44
|
-
fastify.get('*', async (req, reply) => {
|
|
45
|
-
// console.log(disableAuth)
|
|
46
|
-
if (!req.user && !disableAuth) return reply.redirect('/login');
|
|
47
|
-
if (!fs.existsSync(distIndexPath)) {
|
|
48
|
-
return reply
|
|
49
|
-
.code(503)
|
|
50
|
-
.type('text/plain')
|
|
51
|
-
.send('index.html not found in dist. Run: npm run build-app');
|
|
52
|
-
}
|
|
53
|
-
const stream = fs.createReadStream(distIndexPath);
|
|
54
|
-
return reply
|
|
55
|
-
.headers({ 'Cache-Control': 'public, no-cache' })
|
|
56
|
-
.type('text/html')
|
|
57
|
-
.send(stream);
|
|
58
|
-
});
|
|
59
|
-
fastify.get('/assets/:file', async (req, reply) => {
|
|
60
|
-
const stream = fs.createReadStream(path.join(distAssetsDir, req.params.file));
|
|
61
|
-
const ext = path.extname(req.params.file);
|
|
62
|
-
const mime = {
|
|
63
|
-
'.js': 'text/javascript',
|
|
64
|
-
'.css': 'text/css',
|
|
65
|
-
'.woff2': 'application/font-woff',
|
|
66
|
-
'.png': 'image/png',
|
|
67
|
-
}[ext];
|
|
68
|
-
// reply.cacheControl('max-age', '1d');
|
|
69
|
-
return mime
|
|
70
|
-
? reply
|
|
71
|
-
.headers({
|
|
72
|
-
'Cache-Control': 'public, max-age=3600',
|
|
73
|
-
'Content-Encoding': 'identity',
|
|
74
|
-
})
|
|
75
|
-
.type(mime)
|
|
76
|
-
.send(stream)
|
|
77
|
-
: stream;
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export default plugin;
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import config from '../../config.js';
|
|
5
|
+
|
|
6
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const rootDir = path.resolve(__dirname, '../..');
|
|
8
|
+
const distIndexPath = path.join(rootDir, 'dist', 'index.html');
|
|
9
|
+
const distAssetsDir = path.join(rootDir, 'dist', 'assets');
|
|
10
|
+
|
|
11
|
+
const { disableAuth } = config;
|
|
12
|
+
const isProduction = process.env.NODE_ENV === 'production';
|
|
13
|
+
|
|
14
|
+
async function plugin(fastify) {
|
|
15
|
+
// vite server
|
|
16
|
+
if (!isProduction) {
|
|
17
|
+
const vite = await import('vite');
|
|
18
|
+
|
|
19
|
+
const viteServer = await vite.createServer({
|
|
20
|
+
server: {
|
|
21
|
+
middlewareMode: true,
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
// hot reload
|
|
25
|
+
viteServer.watcher.on('all', (d, t) => {
|
|
26
|
+
if (!t.includes('module') && !t.includes('templates')) return;
|
|
27
|
+
// console.log(d, t);
|
|
28
|
+
viteServer.ws.send({ type: 'full-reload' });
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// this is middleware for vite's dev servert
|
|
32
|
+
fastify.addHook('onRequest', async (req, reply) => {
|
|
33
|
+
// const { user } = req.session?.passport || {};
|
|
34
|
+
const next = () => new Promise((resolve) => {
|
|
35
|
+
viteServer.middlewares(req.raw, reply.raw, () => resolve());
|
|
36
|
+
});
|
|
37
|
+
await next();
|
|
38
|
+
});
|
|
39
|
+
fastify.get('*', async () => {});
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// From Build
|
|
44
|
+
fastify.get('*', async (req, reply) => {
|
|
45
|
+
// console.log(disableAuth)
|
|
46
|
+
if (!req.user && !disableAuth) return reply.redirect('/login');
|
|
47
|
+
if (!fs.existsSync(distIndexPath)) {
|
|
48
|
+
return reply
|
|
49
|
+
.code(503)
|
|
50
|
+
.type('text/plain')
|
|
51
|
+
.send('index.html not found in dist. Run: npm run build-app');
|
|
52
|
+
}
|
|
53
|
+
const stream = fs.createReadStream(distIndexPath);
|
|
54
|
+
return reply
|
|
55
|
+
.headers({ 'Cache-Control': 'public, no-cache' })
|
|
56
|
+
.type('text/html')
|
|
57
|
+
.send(stream);
|
|
58
|
+
});
|
|
59
|
+
fastify.get('/assets/:file', async (req, reply) => {
|
|
60
|
+
const stream = fs.createReadStream(path.join(distAssetsDir, req.params.file));
|
|
61
|
+
const ext = path.extname(req.params.file);
|
|
62
|
+
const mime = {
|
|
63
|
+
'.js': 'text/javascript',
|
|
64
|
+
'.css': 'text/css',
|
|
65
|
+
'.woff2': 'application/font-woff',
|
|
66
|
+
'.png': 'image/png',
|
|
67
|
+
}[ext];
|
|
68
|
+
// reply.cacheControl('max-age', '1d');
|
|
69
|
+
return mime
|
|
70
|
+
? reply
|
|
71
|
+
.headers({
|
|
72
|
+
'Cache-Control': 'public, max-age=3600',
|
|
73
|
+
'Content-Encoding': 'identity',
|
|
74
|
+
})
|
|
75
|
+
.type(mime)
|
|
76
|
+
.send(stream)
|
|
77
|
+
: stream;
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export default plugin;
|