@opengis/bi 1.0.11 → 1.0.12
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/assets/charts/bar.png +0 -0
- package/dist/assets/charts/funnel.png +0 -0
- package/dist/assets/charts/no_data.jpg +0 -0
- package/dist/assets/charts/number.png +0 -0
- package/dist/assets/charts/pie.png +0 -0
- package/dist/assets/charts/progress.png +0 -0
- package/dist/assets/charts/stat.png +0 -0
- package/dist/assets/images/bar.png +0 -0
- package/dist/assets/images/funnel.png +0 -0
- package/dist/assets/images/no_data.jpg +0 -0
- package/dist/assets/images/number.png +0 -0
- package/dist/assets/images/pie.png +0 -0
- package/dist/assets/images/progress.png +0 -0
- package/dist/assets/images/stat.png +0 -0
- package/dist/bi.js +1 -1
- package/dist/bi.umd.cjs +723 -113
- package/dist/{import-file-D6RYWvi_.js → import-file-Db7C78fp.js} +43157 -43204
- package/dist/style.css +1 -1
- package/dist/vs-calendar-Ddl6WRL3.js +96 -0
- package/dist/vs-funnel-bar-GbisTylf.js +92 -0
- package/dist/vs-heatmap-CPiim0yg.js +83 -0
- package/dist/vs-map-DuBKvlTI.js +19422 -0
- package/dist/vs-number-CR1H0JTM.js +39 -0
- package/dist/{vs-text-UyIWGqQO.js → vs-text-C3RkizPQ.js} +60 -60
- package/package.json +7 -5
- package/server/routes/dashboard/controllers/dashboard.js +20 -1
- package/server/routes/data/controllers/data.js +31 -19
- package/server/routes/data/controllers/util/chartSQL.js +8 -7
- package/server/routes/data/controllers/util/normalizeData.js +10 -4
- package/server/routes/edit/controllers/dashboard.add.js +5 -1
- package/server/routes/edit/controllers/dashboard.edit.js +5 -1
- package/server/routes/edit/controllers/widget.add.js +23 -7
- package/server/routes/edit/controllers/widget.del.js +1 -1
- package/server/routes/edit/controllers/widget.edit.js +8 -5
- package/server/routes/map/controllers/cluster.js +90 -0
- package/server/routes/map/controllers/clusterVtile.js +144 -0
- package/server/routes/map/controllers/geojson.js +1 -1
- package/server/routes/map/controllers/map.js +63 -0
- package/server/routes/map/controllers/vtile.js +1 -1
- package/server/routes/map/index.mjs +7 -4
- package/server/templates/cls/demo.parcel.object_type.json +12 -0
- package/server/templates/dashboard/demo/funnel.yml +18 -0
- package/server/templates/dashboard/demo/heatmap.yml +18 -0
- package/server/templates/dashboard/demo/index.yml +58 -0
- package/server/templates/dashboard/demo/line.yml +19 -0
- package/server/templates/dashboard/demo/map.yml +13 -0
- package/server/templates/dashboard/demo/pivot.yml +18 -0
- package/server/templates/dashboard/demo/progress.yml +15 -0
- package/server/templates/dashboard/demo/quarterly_revenue.yml +17 -0
- package/server/templates/dashboard/demo/quarterly_revenue_by_product_line.yml +19 -0
- package/server/templates/dashboard/demo/stat.yml +15 -0
- package/server/templates/dashboard/demo/total_products_sold.yml +9 -0
- package/server/templates/dashboard/demo/total_products_sold_by_product_line.yml +12 -0
- package/server/templates/dashboard/demo/total_revenue.yml +10 -0
- package/server/templates/dashboard/demo/total_revenue_by_product_line.yml +20 -0
- package/server/templates/dashboard/demo/vehicle_sales_info.md +17 -0
- package/server/templates/dashboard/demo/waterfall.yml +19 -0
- package/server/templates/dashboard/erobota/bar_area.yml +3 -1
- package/server/templates/dashboard/erobota/bar_culture.yml +1 -1
- package/server/templates/dashboard/erobota/bar_grand.yml +3 -2
- package/server/templates/dashboard/erobota/count_grand.yml +1 -1
- package/server/templates/dashboard/erobota/index.yml +14 -12
- package/server/templates/dashboard/erobota/list_culture.yml +1 -1
- package/server/templates/dashboard/erobota/list_grant.yml +1 -1
- package/server/templates/dashboard/erobota/map.yml +1 -1
- package/server/templates/dashboard/erobota/pie_area.yml +1 -1
- package/server/templates/dashboard/erobota/pie_grant.yml +1 -1
- package/server/templates/dashboard/erobota/total_area.yml +1 -1
- package/server/templates/dashboard/erobota/total_grand.yml +1 -1
- package/server/templates/dashboard/map/index.yml +6 -0
- package/server/templates/dashboard/map/map.yml +13 -0
- package/server/templates/dashboard/map/mapCluster.yml +16 -0
- package/server/templates/dashboard/sales/index.yml +4 -3
- package/server/templates/dashboard/sales/quarterly_revenue.yml +1 -3
- package/server/templates/dashboard/sales/quarterly_revenue_by_product_line.yml +1 -1
- package/server/templates/dashboard/sales/total_products_sold.yml +1 -1
- package/server/templates/dashboard/sales/total_products_sold_by_product_line.yml +2 -1
- package/server/templates/dashboard/sales/total_revenue.yml +1 -1
- package/server/templates/dashboard/sales/total_revenue_by_product_line.yml +4 -1
- package/server/templates/dashboard/test3/quarterly_revenue.yml +1 -1
- package/server/templates/dashboard/test3/widget1.yml +1 -1
- package/server/templates/widget/calendar.yml +14 -0
- package/server/templates/widget/map.yml +15 -0
- package/server/templates/widget/mapCluster.yml +16 -0
- package/server/templates/widget/negative.yml +18 -0
- package/server/templates/widget/negative_profi_expense.yml +23 -0
- package/server/templates/widget/negative_type.yml +24 -0
- package/dist/vs-number-DKF5ptAP.js +0 -34
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { _ as s, c as i, f as o } from "./import-file-Db7C78fp.js";
|
|
2
|
+
import { openBlock as c, createElementBlock as n, toDisplayString as a } from "vue";
|
|
3
|
+
const m = {
|
|
4
|
+
mixins: [i],
|
|
5
|
+
data() {
|
|
6
|
+
return {
|
|
7
|
+
number: ""
|
|
8
|
+
};
|
|
9
|
+
},
|
|
10
|
+
computed: {
|
|
11
|
+
formattedNumber() {
|
|
12
|
+
return o(this.number);
|
|
13
|
+
},
|
|
14
|
+
prefix() {
|
|
15
|
+
var t, e;
|
|
16
|
+
return (t = this.styleData) != null && t.prefix ? (e = this.styleData) == null ? void 0 : e.prefix : "";
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
async mounted() {
|
|
20
|
+
await this.getData(), this.getNumber();
|
|
21
|
+
},
|
|
22
|
+
methods: {
|
|
23
|
+
async getNumber() {
|
|
24
|
+
var t;
|
|
25
|
+
try {
|
|
26
|
+
this.number = this.sourceData[0][Object.keys((t = this.sourceData) == null ? void 0 : t[0])];
|
|
27
|
+
} catch (e) {
|
|
28
|
+
console.error(e);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}, u = { class: "font-[Inter,_Helvetica,_Arial] p-4 w-full text-[28px] pt-[10px] min-h-[130px] border-0" };
|
|
33
|
+
function p(t, e, f, h, d, r) {
|
|
34
|
+
return c(), n("div", u, a(r.prefix) + a(r.formattedNumber), 1);
|
|
35
|
+
}
|
|
36
|
+
const _ = /* @__PURE__ */ s(m, [["render", p]]);
|
|
37
|
+
export {
|
|
38
|
+
_ as default
|
|
39
|
+
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
var ge = Object.defineProperty;
|
|
2
2
|
var ke = (c, e, t) => e in c ? ge(c, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : c[e] = t;
|
|
3
3
|
var k = (c, e, t) => ke(c, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
function
|
|
4
|
+
import { _ as de, c as xe } from "./import-file-Db7C78fp.js";
|
|
5
|
+
import { openBlock as V, createElementBlock as J, createCommentVNode as be } from "vue";
|
|
6
|
+
function D() {
|
|
7
7
|
return {
|
|
8
8
|
async: !1,
|
|
9
9
|
breaks: !1,
|
|
@@ -17,33 +17,33 @@ function j() {
|
|
|
17
17
|
walkTokens: null
|
|
18
18
|
};
|
|
19
19
|
}
|
|
20
|
-
let z =
|
|
20
|
+
let z = D();
|
|
21
21
|
function se(c) {
|
|
22
22
|
z = c;
|
|
23
23
|
}
|
|
24
|
-
const ie = /[&<>"']/,
|
|
24
|
+
const ie = /[&<>"']/, me = new RegExp(ie.source, "g"), re = /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/, we = new RegExp(re.source, "g"), ye = {
|
|
25
25
|
"&": "&",
|
|
26
26
|
"<": "<",
|
|
27
27
|
">": ">",
|
|
28
28
|
'"': """,
|
|
29
29
|
"'": "'"
|
|
30
|
-
}, K = (c) =>
|
|
30
|
+
}, K = (c) => ye[c];
|
|
31
31
|
function b(c, e) {
|
|
32
32
|
if (e) {
|
|
33
33
|
if (ie.test(c))
|
|
34
|
-
return c.replace(
|
|
34
|
+
return c.replace(me, K);
|
|
35
35
|
} else if (re.test(c))
|
|
36
|
-
return c.replace(
|
|
36
|
+
return c.replace(we, K);
|
|
37
37
|
return c;
|
|
38
38
|
}
|
|
39
|
-
const
|
|
39
|
+
const $e = /(^|[^\[])\^/g;
|
|
40
40
|
function f(c, e) {
|
|
41
41
|
let t = typeof c == "string" ? c : c.source;
|
|
42
42
|
e = e || "";
|
|
43
43
|
const n = {
|
|
44
44
|
replace: (s, i) => {
|
|
45
45
|
let r = typeof i == "string" ? i : i.source;
|
|
46
|
-
return r = r.replace(
|
|
46
|
+
return r = r.replace($e, "$1"), t = t.replace(s, r), n;
|
|
47
47
|
},
|
|
48
48
|
getRegex: () => new RegExp(t, e)
|
|
49
49
|
};
|
|
@@ -92,7 +92,7 @@ function _(c, e, t) {
|
|
|
92
92
|
}
|
|
93
93
|
return c.slice(0, n - s);
|
|
94
94
|
}
|
|
95
|
-
function
|
|
95
|
+
function Te(c, e) {
|
|
96
96
|
if (c.indexOf(e[1]) === -1)
|
|
97
97
|
return -1;
|
|
98
98
|
let t = 0;
|
|
@@ -127,7 +127,7 @@ function te(c, e, t, n) {
|
|
|
127
127
|
text: b(r)
|
|
128
128
|
};
|
|
129
129
|
}
|
|
130
|
-
function
|
|
130
|
+
function ze(c, e) {
|
|
131
131
|
const t = c.match(/^(\s+)(?:```)/);
|
|
132
132
|
if (t === null)
|
|
133
133
|
return e;
|
|
@@ -175,7 +175,7 @@ class q {
|
|
|
175
175
|
fences(e) {
|
|
176
176
|
const t = this.rules.block.fences.exec(e);
|
|
177
177
|
if (t) {
|
|
178
|
-
const n = t[0], s =
|
|
178
|
+
const n = t[0], s = ze(n, t[3] || "");
|
|
179
179
|
return {
|
|
180
180
|
type: "code",
|
|
181
181
|
raw: n,
|
|
@@ -455,7 +455,7 @@ ${p}` : p;
|
|
|
455
455
|
if ((n.length - r.length) % 2 === 0)
|
|
456
456
|
return;
|
|
457
457
|
} else {
|
|
458
|
-
const r =
|
|
458
|
+
const r = Te(t[2], "()");
|
|
459
459
|
if (r > -1) {
|
|
460
460
|
const o = (t[0].indexOf("!") === 0 ? 5 : 4) + t[1].length + r;
|
|
461
461
|
t[2] = t[2].substring(0, r), t[0] = t[0].substring(0, o).trim(), t[3] = "";
|
|
@@ -619,25 +619,25 @@ ${p}` : p;
|
|
|
619
619
|
}
|
|
620
620
|
}
|
|
621
621
|
}
|
|
622
|
-
const
|
|
623
|
-
blockquote:
|
|
624
|
-
code:
|
|
625
|
-
def:
|
|
626
|
-
fences:
|
|
627
|
-
heading:
|
|
622
|
+
const Re = /^(?:[ \t]*(?:\n|$))+/, _e = /^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/, Se = /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/, E = /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/, Ie = /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/, le = /(?:[*+-]|\d{1,9}[.)])/, oe = f(/^(?!bull |blockCode|fences|blockquote|heading|html)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html))+?)\n {0,3}(=+|-+) *(?:\n+|$)/).replace(/bull/g, le).replace(/blockCode/g, /(?: {4}| {0,3}\t)/).replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g, / {0,3}>/).replace(/heading/g, / {0,3}#{1,6}/).replace(/html/g, / {0,3}<[^\n>]+>\n/).getRegex(), j = /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/, Ae = /^[^\n]+/, O = /(?!\s*\])(?:\\.|[^\[\]\\])+/, Ee = f(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace("label", O).replace("title", /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex(), Le = f(/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/).replace(/bull/g, le).getRegex(), P = "address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul", H = /<!--(?:-?>|[\s\S]*?(?:-->|$))/, ve = f("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|<![A-Z][\\s\\S]*?(?:>\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$))", "i").replace("comment", H).replace("tag", P).replace("attribute", / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(), ae = f(j).replace("hr", E).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("|table", "").replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", P).getRegex(), qe = f(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph", ae).getRegex(), N = {
|
|
623
|
+
blockquote: qe,
|
|
624
|
+
code: _e,
|
|
625
|
+
def: Ee,
|
|
626
|
+
fences: Se,
|
|
627
|
+
heading: Ie,
|
|
628
628
|
hr: E,
|
|
629
|
-
html:
|
|
629
|
+
html: ve,
|
|
630
630
|
lheading: oe,
|
|
631
|
-
list:
|
|
632
|
-
newline:
|
|
631
|
+
list: Le,
|
|
632
|
+
newline: Re,
|
|
633
633
|
paragraph: ae,
|
|
634
634
|
table: I,
|
|
635
|
-
text:
|
|
636
|
-
}, ne = f("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr", E).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("blockquote", " {0,3}>").replace("code", "(?: {4}| {0,3} )[^\\n]").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", P).getRegex(),
|
|
635
|
+
text: Ae
|
|
636
|
+
}, ne = f("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr", E).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("blockquote", " {0,3}>").replace("code", "(?: {4}| {0,3} )[^\\n]").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", P).getRegex(), Be = {
|
|
637
637
|
...N,
|
|
638
638
|
table: ne,
|
|
639
|
-
paragraph: f(
|
|
640
|
-
},
|
|
639
|
+
paragraph: f(j).replace("hr", E).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("table", ne).replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", P).getRegex()
|
|
640
|
+
}, Ce = {
|
|
641
641
|
...N,
|
|
642
642
|
html: f(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace("comment", H).replace(/tag/g, "(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),
|
|
643
643
|
def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,
|
|
@@ -645,30 +645,30 @@ const ze = /^(?:[ \t]*(?:\n|$))+/, Re = /^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*
|
|
|
645
645
|
fences: I,
|
|
646
646
|
// fences not supported
|
|
647
647
|
lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
|
|
648
|
-
paragraph: f(
|
|
648
|
+
paragraph: f(j).replace("hr", E).replace("heading", ` *#{1,6} *[^
|
|
649
649
|
]`).replace("lheading", oe).replace("|table", "").replace("blockquote", " {0,3}>").replace("|fences", "").replace("|list", "").replace("|html", "").replace("|tag", "").getRegex()
|
|
650
|
-
}, ce = /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,
|
|
650
|
+
}, ce = /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/, Pe = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/, he = /^( {2,}|\\)\n(?!\s*$)/, Ze = /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/, L = "\\p{P}\\p{S}", Me = f(/^((?![*_])[\spunctuation])/, "u").replace(/punctuation/g, L).getRegex(), Qe = /\[[^[\]]*?\]\([^\(\)]*?\)|`[^`]*?`|<[^<>]*?>/g, De = f(/^(?:\*+(?:((?!\*)[punct])|[^\s*]))|^_+(?:((?!_)[punct])|([^\s_]))/, "u").replace(/punct/g, L).getRegex(), je = f("^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)[punct](\\*+)(?=[\\s]|$)|[^punct\\s](\\*+)(?!\\*)(?=[punct\\s]|$)|(?!\\*)[punct\\s](\\*+)(?=[^punct\\s])|[\\s](\\*+)(?!\\*)(?=[punct])|(?!\\*)[punct](\\*+)(?!\\*)(?=[punct])|[^punct\\s](\\*+)(?=[^punct\\s])", "gu").replace(/punct/g, L).getRegex(), Oe = f("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)[punct](_+)(?=[\\s]|$)|[^punct\\s](_+)(?!_)(?=[punct\\s]|$)|(?!_)[punct\\s](_+)(?=[^punct\\s])|[\\s](_+)(?!_)(?=[punct])|(?!_)[punct](_+)(?!_)(?=[punct])", "gu").replace(/punct/g, L).getRegex(), He = f(/\\([punct])/, "gu").replace(/punct/g, L).getRegex(), Ne = f(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace("scheme", /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email", /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex(), Ue = f(H).replace("(?:-->|$)", "-->").getRegex(), Fe = f("^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>").replace("comment", Ue).replace("attribute", /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex(), B = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/, We = f(/^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/).replace("label", B).replace("href", /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/).replace("title", /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex(), pe = f(/^!?\[(label)\]\[(ref)\]/).replace("label", B).replace("ref", O).getRegex(), ue = f(/^!?\[(ref)\](?:\[\])?/).replace("ref", O).getRegex(), Xe = f("reflink|nolink(?!\\()", "g").replace("reflink", pe).replace("nolink", ue).getRegex(), U = {
|
|
651
651
|
_backpedal: I,
|
|
652
652
|
// only used for GFM url
|
|
653
|
-
anyPunctuation:
|
|
654
|
-
autolink:
|
|
655
|
-
blockSkip:
|
|
653
|
+
anyPunctuation: He,
|
|
654
|
+
autolink: Ne,
|
|
655
|
+
blockSkip: Qe,
|
|
656
656
|
br: he,
|
|
657
|
-
code:
|
|
657
|
+
code: Pe,
|
|
658
658
|
del: I,
|
|
659
|
-
emStrongLDelim:
|
|
659
|
+
emStrongLDelim: De,
|
|
660
660
|
emStrongRDelimAst: je,
|
|
661
|
-
emStrongRDelimUnd:
|
|
661
|
+
emStrongRDelimUnd: Oe,
|
|
662
662
|
escape: ce,
|
|
663
|
-
link:
|
|
663
|
+
link: We,
|
|
664
664
|
nolink: ue,
|
|
665
|
-
punctuation:
|
|
665
|
+
punctuation: Me,
|
|
666
666
|
reflink: pe,
|
|
667
|
-
reflinkSearch:
|
|
668
|
-
tag:
|
|
669
|
-
text:
|
|
667
|
+
reflinkSearch: Xe,
|
|
668
|
+
tag: Fe,
|
|
669
|
+
text: Ze,
|
|
670
670
|
url: I
|
|
671
|
-
},
|
|
671
|
+
}, Ge = {
|
|
672
672
|
...U,
|
|
673
673
|
link: f(/^!?\[(label)\]\((.*?)\)/).replace("label", B).getRegex(),
|
|
674
674
|
reflink: f(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label", B).getRegex()
|
|
@@ -679,19 +679,19 @@ const ze = /^(?:[ \t]*(?:\n|$))+/, Re = /^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*
|
|
|
679
679
|
_backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,
|
|
680
680
|
del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,
|
|
681
681
|
text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/
|
|
682
|
-
},
|
|
682
|
+
}, Ve = {
|
|
683
683
|
...Q,
|
|
684
684
|
br: f(he).replace("{2,}", "*").getRegex(),
|
|
685
685
|
text: f(Q.text).replace("\\b_", "\\b_| {2,}\\n").replace(/\{2,\}/g, "*").getRegex()
|
|
686
686
|
}, v = {
|
|
687
687
|
normal: N,
|
|
688
|
-
gfm:
|
|
689
|
-
pedantic:
|
|
688
|
+
gfm: Be,
|
|
689
|
+
pedantic: Ce
|
|
690
690
|
}, S = {
|
|
691
691
|
normal: U,
|
|
692
692
|
gfm: Q,
|
|
693
|
-
breaks:
|
|
694
|
-
pedantic:
|
|
693
|
+
breaks: Ve,
|
|
694
|
+
pedantic: Ge
|
|
695
695
|
};
|
|
696
696
|
class w {
|
|
697
697
|
constructor(e) {
|
|
@@ -1283,9 +1283,9 @@ k(A, "passThroughHooks", /* @__PURE__ */ new Set([
|
|
|
1283
1283
|
"postprocess",
|
|
1284
1284
|
"processAllTokens"
|
|
1285
1285
|
]));
|
|
1286
|
-
class
|
|
1286
|
+
class Je {
|
|
1287
1287
|
constructor(...e) {
|
|
1288
|
-
k(this, "defaults",
|
|
1288
|
+
k(this, "defaults", D());
|
|
1289
1289
|
k(this, "options", this.setOptions);
|
|
1290
1290
|
k(this, "parse", this.parseMarkdown(!0));
|
|
1291
1291
|
k(this, "parseInline", this.parseMarkdown(!1));
|
|
@@ -1456,14 +1456,14 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
1456
1456
|
};
|
|
1457
1457
|
}
|
|
1458
1458
|
}
|
|
1459
|
-
const T = new
|
|
1459
|
+
const T = new Je();
|
|
1460
1460
|
function u(c, e) {
|
|
1461
1461
|
return T.parse(c, e);
|
|
1462
1462
|
}
|
|
1463
1463
|
u.options = u.setOptions = function(c) {
|
|
1464
1464
|
return T.setOptions(c), u.defaults = T.defaults, se(u.defaults), u;
|
|
1465
1465
|
};
|
|
1466
|
-
u.getDefaults =
|
|
1466
|
+
u.getDefaults = D;
|
|
1467
1467
|
u.defaults = z;
|
|
1468
1468
|
u.use = function(...c) {
|
|
1469
1469
|
return T.use(...c), u.defaults = T.defaults, se(u.defaults), u;
|
|
@@ -1488,30 +1488,30 @@ u.walkTokens;
|
|
|
1488
1488
|
u.parseInline;
|
|
1489
1489
|
y.parse;
|
|
1490
1490
|
w.lex;
|
|
1491
|
-
const
|
|
1492
|
-
|
|
1491
|
+
const Ke = {
|
|
1492
|
+
mixins: [xe],
|
|
1493
1493
|
data() {
|
|
1494
1494
|
return {
|
|
1495
1495
|
markedText: null
|
|
1496
1496
|
};
|
|
1497
1497
|
},
|
|
1498
|
-
mounted() {
|
|
1498
|
+
async mounted() {
|
|
1499
1499
|
try {
|
|
1500
|
-
this.markedText = u(this.
|
|
1500
|
+
await this.getData(), this.markedText = u(this.sourceData);
|
|
1501
1501
|
} catch (c) {
|
|
1502
1502
|
console.error(c);
|
|
1503
1503
|
}
|
|
1504
1504
|
}
|
|
1505
|
-
},
|
|
1506
|
-
function
|
|
1507
|
-
return V(), J("div",
|
|
1505
|
+
}, Ye = { class: "relative select-auto h-full py-4 rounded-xl p-4 box-border bg-white custom-scrollbar" }, et = ["innerHTML"];
|
|
1506
|
+
function tt(c, e, t, n, s, i) {
|
|
1507
|
+
return V(), J("div", Ye, [
|
|
1508
1508
|
s.markedText ? (V(), J("div", {
|
|
1509
1509
|
key: 0,
|
|
1510
1510
|
innerHTML: s.markedText
|
|
1511
|
-
}, null, 8,
|
|
1511
|
+
}, null, 8, et)) : be("", !0)
|
|
1512
1512
|
]);
|
|
1513
1513
|
}
|
|
1514
|
-
const
|
|
1514
|
+
const rt = /* @__PURE__ */ de(Ke, [["render", tt]]);
|
|
1515
1515
|
export {
|
|
1516
|
-
|
|
1516
|
+
rt as default
|
|
1517
1517
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengis/bi",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.12",
|
|
4
4
|
"description": "BI data visualization module",
|
|
5
5
|
"main": "dist/bi.js",
|
|
6
6
|
"browser": "dist/bi.umd.cjs",
|
|
@@ -36,17 +36,19 @@
|
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@grpc/grpc-js": "^1.9.13",
|
|
38
38
|
"@grpc/proto-loader": "^0.6.9",
|
|
39
|
-
"carto": "^0.16.3",
|
|
40
39
|
"@mapbox/sphericalmercator": "^1.2.0",
|
|
41
|
-
"@opengis/fastify-table": "^1.1.
|
|
42
|
-
"@opengis/v3-core": "^0.1.
|
|
40
|
+
"@opengis/fastify-table": "^1.1.15",
|
|
41
|
+
"@opengis/v3-core": "^0.1.103",
|
|
42
|
+
"@opengis/v3-filter": "^0.0.31",
|
|
43
43
|
"axios": "^1.3.1",
|
|
44
|
+
"carto": "^0.16.3",
|
|
44
45
|
"cross-env": "^7.0.3",
|
|
45
46
|
"d3-format": "^3.1.0",
|
|
46
47
|
"echarts": "^5.5.1",
|
|
47
48
|
"fastify": "^4.26.1",
|
|
48
49
|
"fastify-plugin": "^4.0.0",
|
|
49
50
|
"js-yaml": "^4.1.0",
|
|
51
|
+
"maplibre-gl": "^4.7.1",
|
|
50
52
|
"marked": "^14.1.2",
|
|
51
53
|
"vite": "^5.1.5",
|
|
52
54
|
"vue": "^3.4.27",
|
|
@@ -64,4 +66,4 @@
|
|
|
64
66
|
"vitepress-plugin-tabs": "^0.5.0",
|
|
65
67
|
"vitepress-sidebar": "^1.22.0"
|
|
66
68
|
}
|
|
67
|
-
}
|
|
69
|
+
}
|
|
@@ -45,12 +45,31 @@ export default async function data({
|
|
|
45
45
|
return { message: 'not found ' + id, status: 404 };
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
if (index?.filters?.filter((el) => el?.type === 'Check')?.length) {
|
|
49
|
+
await Promise.all(index.filters.filter((el) => el?.type === 'Check' && el?.data).map(async (el) => {
|
|
50
|
+
const options = await getTemplate('cls', el.data);
|
|
51
|
+
Object.assign(el, { options });
|
|
52
|
+
}));
|
|
53
|
+
}
|
|
54
|
+
|
|
48
55
|
|
|
49
56
|
const data = index;
|
|
50
57
|
data.type = 'file';
|
|
51
58
|
const { table } = data?.data || { table: data?.table_name };
|
|
52
59
|
// console.log(fileData)
|
|
53
|
-
const widgets = fileData
|
|
60
|
+
const widgets = fileData
|
|
61
|
+
.filter((el) => el[0] !== 'index.yml')
|
|
62
|
+
.map((el) =>
|
|
63
|
+
el[1].data
|
|
64
|
+
? {
|
|
65
|
+
name: el[0].split('.')[0],
|
|
66
|
+
type: el[1].type,
|
|
67
|
+
title: el[1].title,
|
|
68
|
+
style: el[1].style,
|
|
69
|
+
data: el[1].data
|
|
70
|
+
}
|
|
71
|
+
: { name: el[0].split('.')[0], title: el[1] }
|
|
72
|
+
);
|
|
54
73
|
|
|
55
74
|
const { fields = [] } = table ? await pg.query(`select * from ${table} limit 1`) : {};
|
|
56
75
|
|
|
@@ -12,8 +12,7 @@ export default async function data({
|
|
|
12
12
|
pg = pgClients.client, funcs = {}, query = {},
|
|
13
13
|
}) {
|
|
14
14
|
const time = Date.now();
|
|
15
|
-
const {
|
|
16
|
-
const { dashboard, widget } = query;
|
|
15
|
+
const { dashboard, widget, filter, search, samples } = query;
|
|
17
16
|
|
|
18
17
|
if (!widget && !dashboard) {
|
|
19
18
|
return { message: 'not enough params: widget or dashboard required', status: 400 };
|
|
@@ -24,56 +23,61 @@ export default async function data({
|
|
|
24
23
|
await pg.query(`select dashboard_id as id, table_name as "tableName" from bi.dashboard where $1 in (dashboard_id, name)`, [dashboard]).then((res1) => res1.rows?.[0] || {}) : {};
|
|
25
24
|
|
|
26
25
|
|
|
27
|
-
if (!dashboardData && dashboard && !id)
|
|
28
|
-
|
|
29
|
-
// return { t: 111, data: dashboardData, dashboard }
|
|
30
|
-
|
|
31
|
-
const widgetData = dashboard ? dashboardData?.find(el => el[0]?.includes(widget))?.[1] : await getTemplate('widget', widget);
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if (dashboardData && !widgetData) {
|
|
35
|
-
return widgetData
|
|
26
|
+
if (!dashboardData && dashboard && !id) {
|
|
27
|
+
return { message: `dashboard not found: ${dashboard}`, status: 404 };
|
|
36
28
|
}
|
|
37
29
|
|
|
30
|
+
const widgetData = dashboard ? dashboardData?.find(el => el[0]?.includes(widget || 'index'))?.[1] : await getTemplate('widget', widget);
|
|
31
|
+
|
|
38
32
|
if (!id && !dashboardData && !widgetData) {
|
|
39
|
-
return { message: {
|
|
33
|
+
return { message: { error: `not found`, widget, dashboard }, status: 404 };
|
|
40
34
|
}
|
|
41
35
|
|
|
42
36
|
const q = `select *, coalesce(data::jsonb, '{}'::jsonb) || jsonb_build_object('table', table_name) as data from bi.widget where dashboard_id=$1 and name=$2`;
|
|
43
|
-
const { type, text, data, controls, style, options } = widgetData || await pg.query(q, [id || dashboard, widget]).then((res1) => res1.rows?.[0] || {});
|
|
37
|
+
const { type, text, data = {}, controls, style, options } = widgetData || await pg.query(q, [id || dashboard, widget]).then((res1) => res1.rows?.[0] || {});
|
|
44
38
|
|
|
45
39
|
if (typeof widgetData === 'string') {
|
|
46
40
|
return { title: false, source: widgetData };
|
|
47
41
|
}
|
|
48
42
|
|
|
49
|
-
if (!data?.table && tableName) {
|
|
50
|
-
Object.assign(data, { table: tableName });
|
|
43
|
+
if (!data?.table && tableName || widgetData?.table_name) {
|
|
44
|
+
Object.assign(data, { table: tableName || widgetData?.table_name });
|
|
51
45
|
}
|
|
52
46
|
|
|
53
47
|
if (!data?.table) {
|
|
54
48
|
return { error: /* json.error || */ `invalid ${widget ? 'widget' : 'dashboard'}: 1`, status: 500 };
|
|
55
49
|
}
|
|
56
50
|
|
|
51
|
+
// types
|
|
52
|
+
const { fields: cols } = await pg.queryCache(`select * from ${data.table} limit 0`);
|
|
53
|
+
const columnTypes = cols.map(el => ({ name: el.name, type: pg.pgType[el.dataTypeID] }))
|
|
54
|
+
|
|
57
55
|
// data param
|
|
58
|
-
const { x, metric, table, where, groupby, xName } = normalizeData(data, query);
|
|
56
|
+
const { x, metric, table, where, groupby, xName } = normalizeData(data, query, columnTypes);
|
|
59
57
|
|
|
60
58
|
// auto Index
|
|
61
59
|
if (pg.pk[data.table]) {
|
|
62
60
|
autoIndex({ table: data.table, columns: [data?.time].concat([xName]).concat([groupby]).filter(el => el) }).catch(err => console.log(err))
|
|
63
61
|
}
|
|
64
62
|
|
|
63
|
+
|
|
65
64
|
// get group
|
|
66
65
|
const groupData = groupby ? await pg.query(`select ${groupby} as name ,count(*) from ${table} group by ${groupby} order by count(*) desc limit 20`).then(el => el.rows) : null;
|
|
67
66
|
|
|
68
67
|
if (query.sql === '2') return { x, metric, table, data, groupData };
|
|
69
68
|
|
|
70
|
-
const
|
|
69
|
+
const order = data.order || (type === 'listbar' ? 'metric desc' : null);
|
|
70
|
+
|
|
71
|
+
const { optimizedSQL = `select * from ${table}` } = filter || search ? await funcs.getFilterSQL({
|
|
72
|
+
pg, table, filter, search,
|
|
73
|
+
}) : {};
|
|
71
74
|
|
|
75
|
+
const sql = (chartSQL[type] || chartSQL['chart'])({ where, metric, table: `(${optimizedSQL})q`, x, groupData, groupby, order, samples });
|
|
72
76
|
|
|
73
77
|
if (query.sql) return sql;
|
|
74
78
|
|
|
75
79
|
if (!sql || sql?.includes('undefined')) {
|
|
76
|
-
return { message: { error: 'invalid sql', type, sql, where, metric, table
|
|
80
|
+
return { message: { error: 'invalid sql', type, sql, where, metric, table: `(${optimizedSQL})q`, x, groupData, groupby }, status: 500 };
|
|
77
81
|
}
|
|
78
82
|
|
|
79
83
|
const { rows, fields } = await pg.query(sql); // test with limit
|
|
@@ -87,12 +91,20 @@ export default async function data({
|
|
|
87
91
|
dimensionsType: fields.map(el => pg.pgType[el.dataTypeID]),
|
|
88
92
|
type,
|
|
89
93
|
|
|
90
|
-
text: text ? text : data.text,
|
|
94
|
+
text: text ? text : (widgetData?.title || data.text),
|
|
91
95
|
//data: query.format === 'data' ? dimensions.map(el => rows.map(r => r[el])) : undefined,
|
|
92
96
|
source: query.format === 'array' ? dimensions.map(el => rows.map(r => r[el])) : rows,
|
|
93
97
|
style,
|
|
94
98
|
options,
|
|
95
99
|
controls,
|
|
100
|
+
params: {
|
|
101
|
+
x,
|
|
102
|
+
metric,
|
|
103
|
+
table,
|
|
104
|
+
groupby,
|
|
105
|
+
sql: funcs?.config.local ? optimizedSQL : undefined,
|
|
106
|
+
},
|
|
107
|
+
columnTypes,
|
|
96
108
|
};
|
|
97
109
|
return res;
|
|
98
110
|
|
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
function number({ metric, where, table }) {
|
|
2
|
-
const sql = `select ${metric} from ${table} where ${where}`
|
|
1
|
+
function number({ metric, where, table, samples }) {
|
|
2
|
+
const sql = `select ${metric} from ${table} where ${where} ${samples ? 'limit 10' : ''}`
|
|
3
3
|
return sql;
|
|
4
4
|
}
|
|
5
|
-
function table({ columns, table, where }) {
|
|
6
|
-
return `select ${columns.map(el => el.name || el)}::text from ${table} where ${where} limit 20 `
|
|
5
|
+
function table({ columns, table, where, samples }) {
|
|
6
|
+
return `select ${columns.map(el => el.name || el)}::text from ${table} where ${where} ${samples ? 'limit 10' : 'limit 20'} `
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
function chart({ metric, where, table, x, groupby, groupData }) {
|
|
9
|
+
function chart({ metric, where, table, x, groupby, groupData, order, samples }) {
|
|
10
10
|
|
|
11
|
-
const metricData = groupData?.map(el => `${metric} filter (where ${groupby}='${el.name}') as "${el.name}"`).join(',') || metric
|
|
11
|
+
const metricData = groupData?.map(el => `${metric} filter (where ${groupby}='${el.name}') as "${el.name}"`).join(',') || `${metric} as metric`
|
|
12
12
|
const sql = `select ${x}, ${metricData}
|
|
13
13
|
from ${table}
|
|
14
14
|
where ${where}
|
|
15
15
|
group by ${x}
|
|
16
|
-
order by ${x}
|
|
16
|
+
order by ${order || x}
|
|
17
|
+
${samples ? 'limit 10' : ''}`;
|
|
17
18
|
return sql;
|
|
18
19
|
}
|
|
19
20
|
|
|
@@ -1,15 +1,21 @@
|
|
|
1
|
-
function normalizeData(data, query = {}) {
|
|
1
|
+
function normalizeData(data, query = {}, columnTypes = []) {
|
|
2
|
+
['x', 'groupby', 'granularity'].forEach(el => {
|
|
3
|
+
//console.log(el, query[el], columnTypes.find(col => col.name == query[el]))
|
|
4
|
+
if (!columnTypes.find(col => col.name == query[el])) { delete query[el]; }
|
|
5
|
+
})
|
|
2
6
|
|
|
7
|
+
if (!columnTypes.find(col => col.type === 'numeric' && col.name == query.metric)) { delete query.metric; }
|
|
3
8
|
|
|
4
|
-
const
|
|
9
|
+
const xName = query.x || (Array.isArray(data.x) ? data.x[0] : data.x);
|
|
10
|
+
const xTYpe = columnTypes.find(el => el.name == xName)?.type;
|
|
5
11
|
|
|
12
|
+
const granularity = xTYpe === 'date' ? (query.granularity || data.granularity || 'year') : null;
|
|
6
13
|
|
|
7
|
-
const xName = Array.isArray(data.x) ? data.x[0] : data.x || query.x;
|
|
8
14
|
|
|
9
15
|
const x = (granularity ? `date_trunc('${granularity}',${xName})::date` : null) || xName;
|
|
10
16
|
|
|
11
17
|
const metrics = Array.isArray(data.metrics) ? data.metrics : [data.metrics];
|
|
12
|
-
const metric = metrics.length ? metrics?.filter(el => el).map(el => `${el.operator || 'sum'}(${el.name || el})`) : 'count(*)';
|
|
18
|
+
const metric = (query.metric ? `sum(${query.metric})` : null) || (metrics.length ? metrics?.filter(el => el).map(el => `${el.operator || 'sum'}(${el.name || el})`) : 'count(*)');
|
|
13
19
|
|
|
14
20
|
const table = data.table;
|
|
15
21
|
const where = data.query || 'true';
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
export default async function widgetAdd({ pg, funcs, params = {}, body }) {
|
|
2
2
|
try {
|
|
3
3
|
const time = Date.now();
|
|
4
|
-
|
|
4
|
+
const tableName = body.table_name;
|
|
5
|
+
const checkTable = await pg.query(`select * from bi.dashboard where $1 in (table_name)`, [
|
|
6
|
+
tableName
|
|
7
|
+
]);
|
|
8
|
+
if (!checkTable.rows.length) return { message: 'bad params', status: 401 };
|
|
5
9
|
const res = await funcs.dataInsert({
|
|
6
10
|
table: 'bi.dashboard',
|
|
7
11
|
data: body
|
|
@@ -8,7 +8,11 @@ export default async function dashboardEdit({
|
|
|
8
8
|
status: 400,
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
|
-
|
|
11
|
+
const tableName = body.table_name;
|
|
12
|
+
const checkTable = await pg.query(`select * from bi.dashboard where $1 in (table_name)`, [
|
|
13
|
+
tableName
|
|
14
|
+
]);
|
|
15
|
+
if (!checkTable.rows.length) return { message: 'bad params', status: 401 };
|
|
12
16
|
const { name: dashboardName } = params;
|
|
13
17
|
const row = await pg.query(`select dashboard_id from bi.dashboard where $1 in (dashboard_id, name)`, [dashboardName]).then((res1) => res1.rows?.[0] || {});
|
|
14
18
|
const { dashboard_id: dashboardId } = row;
|
|
@@ -1,15 +1,26 @@
|
|
|
1
|
-
export default async function widgetAdd({
|
|
2
|
-
pg, funcs, params = {}, body = {},
|
|
3
|
-
}) {
|
|
1
|
+
export default async function widgetAdd({ pg, funcs, params = {}, body = {} }) {
|
|
4
2
|
const { name: dashboardName } = params;
|
|
5
3
|
if (!dashboardName) {
|
|
6
4
|
return { message: 'not enough params: id', status: 400 };
|
|
7
5
|
}
|
|
8
|
-
|
|
6
|
+
const tableName = body.table_name;
|
|
9
7
|
try {
|
|
10
|
-
const row = await pg
|
|
8
|
+
const row = await pg
|
|
9
|
+
.query(
|
|
10
|
+
`select dashboard_id, widgets, panels from bi.dashboard where $1 in (dashboard_id,name)`,
|
|
11
|
+
[dashboardName]
|
|
12
|
+
)
|
|
13
|
+
.then((res) => res.rows?.[0] || {});
|
|
14
|
+
|
|
15
|
+
const checkTable = await pg.query(`select * from bi.widget where $1 in (table_name)`, [
|
|
16
|
+
tableName
|
|
17
|
+
]);
|
|
18
|
+
if (!checkTable.rows.length) return { message: 'bad params', status: 401 };
|
|
19
|
+
|
|
11
20
|
const { dashboard_id: dashboardId } = row;
|
|
12
21
|
|
|
22
|
+
const generatedName = generateUniqueName(body.type);
|
|
23
|
+
body.name = generatedName;
|
|
13
24
|
const res = await funcs.dataUpdate({
|
|
14
25
|
table: 'bi.dashboard',
|
|
15
26
|
id: dashboardId,
|
|
@@ -20,14 +31,19 @@ export default async function widgetAdd({
|
|
|
20
31
|
});
|
|
21
32
|
const res2 = await funcs.dataInsert({
|
|
22
33
|
table: 'bi.widget',
|
|
23
|
-
data: { ...body, data: body, dashboard_id: dashboardId }
|
|
34
|
+
data: { ...body, data: body, dashboard_id: dashboardId }
|
|
24
35
|
});
|
|
25
36
|
return {
|
|
26
37
|
message: `Added widget to ${dashboardName}`,
|
|
27
38
|
status: 200,
|
|
28
|
-
rows: res
|
|
39
|
+
rows: res
|
|
29
40
|
};
|
|
30
41
|
} catch (err) {
|
|
31
42
|
return { error: err.toString(), status: 500 };
|
|
32
43
|
}
|
|
33
44
|
}
|
|
45
|
+
function generateUniqueName(prefix = 'bar') {
|
|
46
|
+
const randomPart = Math.floor(Math.random() * 10000);
|
|
47
|
+
const timestamp = Date.now();
|
|
48
|
+
return `${prefix}_${randomPart}_${timestamp}`;
|
|
49
|
+
}
|