@lobb-js/lobb-ext-reports 0.3.2 → 0.4.0
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/index.d.ts +2 -0
- package/dist/index.js +20 -0
- package/dist/lib/components/dv_fields_buttons/query_ai_button/index.svelte +27 -0
- package/dist/lib/components/dv_fields_buttons/query_ai_button/index.svelte.d.ts +14 -0
- package/dist/lib/components/pages/reports/components/chart.svelte +131 -0
- package/dist/lib/components/pages/reports/components/chart.svelte.d.ts +14 -0
- package/dist/lib/components/pages/reports/components/charts/chartJs.svelte +42 -0
- package/dist/lib/components/pages/reports/components/charts/chartJs.svelte.d.ts +14 -0
- package/dist/lib/components/pages/reports/components/charts/table.svelte +36 -0
- package/dist/lib/components/pages/reports/components/charts/table.svelte.d.ts +14 -0
- package/dist/lib/components/pages/reports/components/report.svelte +156 -0
- package/dist/lib/components/pages/reports/components/report.svelte.d.ts +14 -0
- package/dist/lib/components/pages/reports/index.svelte +141 -0
- package/dist/lib/components/pages/reports/index.svelte.d.ts +14 -0
- package/dist/lib/index.d.ts +0 -0
- package/dist/lib/index.js +2 -0
- package/dist/lib/utils.d.ts +12 -0
- package/dist/lib/utils.js +5 -0
- package/dist/tests/analytics.spec.d.ts +1 -0
- package/dist/tests/analytics.spec.js +17 -0
- package/dist/tests/package.json +1 -0
- package/dist/tests/playwright.config.cjs +27 -0
- package/dist/tests/playwright.config.d.cts +2 -0
- package/package.json +8 -4
- package/.dockerignore +0 -7
- package/.env.example +0 -10
- package/.vscode/settings.json +0 -5
- package/CHANGELOG.md +0 -141
- package/lobb.ts +0 -55
- package/scripts/postpublish.sh +0 -12
- package/scripts/prepublish.sh +0 -17
- package/studio/app.html +0 -12
- package/studio/routes/+layout.svelte +0 -7
- package/studio/routes/+layout.ts +0 -1
- package/studio/routes/[...path]/+page.svelte +0 -6
- package/svelte.config.js +0 -24
- package/todo.md +0 -11
- package/tsconfig.app.json +0 -27
- package/tsconfig.json +0 -13
- package/tsconfig.node.json +0 -26
- package/vite.config.ts +0 -8
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import Reports from "./lib/components/pages/reports/index.svelte";
|
|
2
|
+
import QueryAiButton from "./lib/components/dv_fields_buttons/query_ai_button/index.svelte";
|
|
3
|
+
export default function extension(utils) {
|
|
4
|
+
return {
|
|
5
|
+
name: "reports",
|
|
6
|
+
components: {
|
|
7
|
+
"dvFields.topRight.reports_charts.query": QueryAiButton,
|
|
8
|
+
"pages.analytics": Reports,
|
|
9
|
+
},
|
|
10
|
+
dashboardNavs: {
|
|
11
|
+
middle: [
|
|
12
|
+
{
|
|
13
|
+
href: "/studio/extensions/reports/analytics",
|
|
14
|
+
icon: utils.components.Icons.ChartNoAxesCombined,
|
|
15
|
+
label: "Analytics",
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { ExtensionProps } from "@lobb-js/studio";
|
|
3
|
+
|
|
4
|
+
let { utils, value = $bindable() }: ExtensionProps = $props();
|
|
5
|
+
|
|
6
|
+
let systemMessage = `You are an expert assistant specialized in generating PostgreSQL read-only queries for analytics and reporting purposes. Your job is to translate user requests written in natural language into accurate, efficient, and well-structured SQL SELECT queries. Only respond with a raw PostgreSQL SELECT query — do not include any markdown formatting, code blocks, or explanations.. This is the schema of the database: (${JSON.stringify(utils.ctx.meta.collections)})`;
|
|
7
|
+
|
|
8
|
+
const componentProps: any = {
|
|
9
|
+
title: "Generate the query with AI",
|
|
10
|
+
description: "Describe to the AI the query you want to generate",
|
|
11
|
+
class: "h-7 px-3 text-xs font-normal",
|
|
12
|
+
variant: "outline",
|
|
13
|
+
// format: {
|
|
14
|
+
// type: 'json_object'
|
|
15
|
+
// },
|
|
16
|
+
messages: [
|
|
17
|
+
{
|
|
18
|
+
role: "system",
|
|
19
|
+
content: systemMessage,
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
};
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<utils.components.LlmButton bind:value {...componentProps}>
|
|
26
|
+
Generate with AI
|
|
27
|
+
</utils.components.LlmButton>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
declare const __propDef: {
|
|
3
|
+
props: Record<string, never>;
|
|
4
|
+
events: {
|
|
5
|
+
[evt: string]: CustomEvent<any>;
|
|
6
|
+
};
|
|
7
|
+
slots: {};
|
|
8
|
+
};
|
|
9
|
+
export type IndexProps = typeof __propDef.props;
|
|
10
|
+
export type IndexEvents = typeof __propDef.events;
|
|
11
|
+
export type IndexSlots = typeof __propDef.slots;
|
|
12
|
+
export default class Index extends SvelteComponentTyped<IndexProps, IndexEvents, IndexSlots> {
|
|
13
|
+
}
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { ExtensionProps } from "@lobb-js/studio";
|
|
3
|
+
import Table from "./charts/table.svelte";
|
|
4
|
+
import ChartJs from "./charts/chartJs.svelte";
|
|
5
|
+
|
|
6
|
+
interface Props extends ExtensionProps {
|
|
7
|
+
chartRecord: any;
|
|
8
|
+
onChartDeleted?: () => Promise<void>;
|
|
9
|
+
onChartEdited?: () => Promise<void>;
|
|
10
|
+
context?: Record<string, any>;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const {
|
|
14
|
+
chartRecord,
|
|
15
|
+
onChartDeleted,
|
|
16
|
+
onChartEdited,
|
|
17
|
+
context,
|
|
18
|
+
...props
|
|
19
|
+
}: Props = $props();
|
|
20
|
+
|
|
21
|
+
const utils = props.utils;
|
|
22
|
+
const { UpdateDetailViewButton, Button } = utils.components;
|
|
23
|
+
const icons = utils.components.Icons;
|
|
24
|
+
let dataPromise = $state(getChartData());
|
|
25
|
+
|
|
26
|
+
async function getChartData() {
|
|
27
|
+
const response = await utils.lobb.findOne(
|
|
28
|
+
"reports_charts",
|
|
29
|
+
chartRecord.id,
|
|
30
|
+
{
|
|
31
|
+
action: "run_query",
|
|
32
|
+
context: JSON.stringify(context),
|
|
33
|
+
},
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
const result = await response.json();
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async function handleChartDelete() {
|
|
41
|
+
const result = await utils.showDialog(
|
|
42
|
+
"Are you sure?",
|
|
43
|
+
"This will delete that chart you selected.",
|
|
44
|
+
);
|
|
45
|
+
if (result) {
|
|
46
|
+
await utils.lobb.deleteOne("reports_charts", chartRecord.id);
|
|
47
|
+
if (onChartDeleted) {
|
|
48
|
+
await onChartDeleted();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async function handleEditOnSuccessfull() {
|
|
54
|
+
if (onChartEdited) {
|
|
55
|
+
await onChartEdited();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
</script>
|
|
59
|
+
|
|
60
|
+
<div class="gridContainer h-96 rounded-md border bg-background">
|
|
61
|
+
<div class="flex items-center justify-between border-b p-2 text-sm">
|
|
62
|
+
<div>{chartRecord.title}</div>
|
|
63
|
+
<div class="flex">
|
|
64
|
+
<UpdateDetailViewButton
|
|
65
|
+
collectionName="reports_charts"
|
|
66
|
+
recordId={chartRecord.id}
|
|
67
|
+
variant="ghost"
|
|
68
|
+
class="h-7 w-7 text-muted-foreground hover:bg-transparent"
|
|
69
|
+
Icon={icons.Pencil}
|
|
70
|
+
onSuccessfullSave={handleEditOnSuccessfull}
|
|
71
|
+
></UpdateDetailViewButton>
|
|
72
|
+
<Button
|
|
73
|
+
class="h-6 w-6 text-muted-foreground hover:bg-transparent"
|
|
74
|
+
variant="ghost"
|
|
75
|
+
size="icon"
|
|
76
|
+
Icon={icons.Trash}
|
|
77
|
+
onclick={handleChartDelete}
|
|
78
|
+
></Button>
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
81
|
+
<div class="flex items-center justify-center overflow-auto">
|
|
82
|
+
<svelte:boundary>
|
|
83
|
+
{#snippet failed(error, reset)}
|
|
84
|
+
<div
|
|
85
|
+
class="flex flex-col gap-2 p-2 bg-red-100 border border-red-500 h-full"
|
|
86
|
+
>
|
|
87
|
+
<div>{error}</div>
|
|
88
|
+
<button
|
|
89
|
+
class="border border-red-500 w-fit px-4 rounded-md hover:bg-red-500"
|
|
90
|
+
onclick={reset}>Reset</button
|
|
91
|
+
>
|
|
92
|
+
</div>
|
|
93
|
+
{/snippet}
|
|
94
|
+
{#await dataPromise}
|
|
95
|
+
<div
|
|
96
|
+
class="flex flex-col gap-4 h-full w-full absolute justify-center items-center"
|
|
97
|
+
>
|
|
98
|
+
<icons.LoaderCircle
|
|
99
|
+
class="animate-spin opacity-50"
|
|
100
|
+
size="50"
|
|
101
|
+
/>
|
|
102
|
+
<div class="flex flex-col items-center justify-center">
|
|
103
|
+
<div class="text-muted-foreground">
|
|
104
|
+
Loading the chart...
|
|
105
|
+
</div>
|
|
106
|
+
<div class="text-muted-foreground text-xs">
|
|
107
|
+
Loading chart's data
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
</div>
|
|
111
|
+
{:then data}
|
|
112
|
+
{#if data.type === "table"}
|
|
113
|
+
<Table input={data.input} {...props} />
|
|
114
|
+
{:else if data.type === "chartjs"}
|
|
115
|
+
<ChartJs input={data.input} {...props} />
|
|
116
|
+
{:else}
|
|
117
|
+
<div class="text-muted-foreground">
|
|
118
|
+
The ({data.type}) chart type is unsupported
|
|
119
|
+
</div>
|
|
120
|
+
{/if}
|
|
121
|
+
{/await}
|
|
122
|
+
</svelte:boundary>
|
|
123
|
+
</div>
|
|
124
|
+
</div>
|
|
125
|
+
|
|
126
|
+
<style>
|
|
127
|
+
.gridContainer {
|
|
128
|
+
display: grid;
|
|
129
|
+
grid-template-rows: auto 1fr;
|
|
130
|
+
}
|
|
131
|
+
</style>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
declare const __propDef: {
|
|
3
|
+
props: Record<string, never>;
|
|
4
|
+
events: {
|
|
5
|
+
[evt: string]: CustomEvent<any>;
|
|
6
|
+
};
|
|
7
|
+
slots: {};
|
|
8
|
+
};
|
|
9
|
+
export type ChartProps = typeof __propDef.props;
|
|
10
|
+
export type ChartEvents = typeof __propDef.events;
|
|
11
|
+
export type ChartSlots = typeof __propDef.slots;
|
|
12
|
+
export default class Chart extends SvelteComponentTyped<ChartProps, ChartEvents, ChartSlots> {
|
|
13
|
+
}
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { ExtensionProps } from "@lobb-js/studio";
|
|
3
|
+
|
|
4
|
+
import { onMount } from 'svelte';
|
|
5
|
+
import { Chart } from 'chart.js/auto';
|
|
6
|
+
import { merge } from 'lodash-es';
|
|
7
|
+
|
|
8
|
+
interface Props extends ExtensionProps {
|
|
9
|
+
input: any;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const { input }: Props = $props();
|
|
13
|
+
|
|
14
|
+
let canvas: HTMLCanvasElement;
|
|
15
|
+
let chart: Chart;
|
|
16
|
+
|
|
17
|
+
onMount(() => {
|
|
18
|
+
if (canvas) {
|
|
19
|
+
const ctx = canvas.getContext('2d');
|
|
20
|
+
if (ctx) {
|
|
21
|
+
chart = new Chart(
|
|
22
|
+
ctx,
|
|
23
|
+
merge(
|
|
24
|
+
{
|
|
25
|
+
options: {
|
|
26
|
+
responsive: true,
|
|
27
|
+
maintainAspectRatio: false
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
$state.snapshot(input)
|
|
31
|
+
)
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return () => {
|
|
37
|
+
chart?.destroy();
|
|
38
|
+
};
|
|
39
|
+
});
|
|
40
|
+
</script>
|
|
41
|
+
|
|
42
|
+
<canvas bind:this={canvas}></canvas>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
declare const __propDef: {
|
|
3
|
+
props: Record<string, never>;
|
|
4
|
+
events: {
|
|
5
|
+
[evt: string]: CustomEvent<any>;
|
|
6
|
+
};
|
|
7
|
+
slots: {};
|
|
8
|
+
};
|
|
9
|
+
export type ChartJsProps = typeof __propDef.props;
|
|
10
|
+
export type ChartJsEvents = typeof __propDef.events;
|
|
11
|
+
export type ChartJsSlots = typeof __propDef.slots;
|
|
12
|
+
export default class ChartJs extends SvelteComponentTyped<ChartJsProps, ChartJsEvents, ChartJsSlots> {
|
|
13
|
+
}
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { ExtensionProps } from "@lobb-js/studio";
|
|
3
|
+
|
|
4
|
+
interface Props extends ExtensionProps {
|
|
5
|
+
input: any;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const { input, utils }: Props = $props();
|
|
9
|
+
|
|
10
|
+
const { data } = input;
|
|
11
|
+
const { Table } = utils.components;
|
|
12
|
+
|
|
13
|
+
const columns = data.length
|
|
14
|
+
? Object.keys(data[0]).map((column) => {
|
|
15
|
+
return {
|
|
16
|
+
id: column,
|
|
17
|
+
};
|
|
18
|
+
})
|
|
19
|
+
: null;
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<div class="relative h-full w-full">
|
|
23
|
+
{#if columns}
|
|
24
|
+
<Table
|
|
25
|
+
{data}
|
|
26
|
+
{columns}
|
|
27
|
+
selectByColumn={null}
|
|
28
|
+
localSorting={true}
|
|
29
|
+
showLastRowBorder={true}
|
|
30
|
+
showLastColumnBorder={true}
|
|
31
|
+
unifiedBgColor="bg-background"
|
|
32
|
+
></Table>
|
|
33
|
+
{:else}
|
|
34
|
+
<div class="flex justify-center items-center h-full">No Results</div>
|
|
35
|
+
{/if}
|
|
36
|
+
</div>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
declare const __propDef: {
|
|
3
|
+
props: Record<string, never>;
|
|
4
|
+
events: {
|
|
5
|
+
[evt: string]: CustomEvent<any>;
|
|
6
|
+
};
|
|
7
|
+
slots: {};
|
|
8
|
+
};
|
|
9
|
+
export type TableProps = typeof __propDef.props;
|
|
10
|
+
export type TableEvents = typeof __propDef.events;
|
|
11
|
+
export type TableSlots = typeof __propDef.slots;
|
|
12
|
+
export default class Table extends SvelteComponentTyped<TableProps, TableEvents, TableSlots> {
|
|
13
|
+
}
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { ExtensionProps } from "@lobb-js/studio";
|
|
3
|
+
import type { DateRange } from "bits-ui";
|
|
4
|
+
import Chart from "./chart.svelte";
|
|
5
|
+
|
|
6
|
+
interface Props extends ExtensionProps {
|
|
7
|
+
reportId: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const props: Props = $props();
|
|
11
|
+
const { intlDate } = props.utils;
|
|
12
|
+
const {
|
|
13
|
+
SidebarTrigger,
|
|
14
|
+
CreateDetailViewButton,
|
|
15
|
+
Icons,
|
|
16
|
+
RangeCalendarButton,
|
|
17
|
+
} = props.utils.components;
|
|
18
|
+
|
|
19
|
+
let dateRangeValue: DateRange = $state({
|
|
20
|
+
start: intlDate
|
|
21
|
+
.today(intlDate.getLocalTimeZone())
|
|
22
|
+
.subtract({ days: 30 }),
|
|
23
|
+
end: intlDate.today(intlDate.getLocalTimeZone()),
|
|
24
|
+
});
|
|
25
|
+
let context = $derived({
|
|
26
|
+
dateRange: {
|
|
27
|
+
start: dateRangeValue.start?.toString(),
|
|
28
|
+
end: dateRangeValue.end?.toString(),
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
let report: any = $state(null);
|
|
33
|
+
let chartsPromise = $state(getCharts());
|
|
34
|
+
|
|
35
|
+
async function getCharts() {
|
|
36
|
+
const reportsResponse = await props.utils.lobb.findAll(
|
|
37
|
+
"reports_dashboards",
|
|
38
|
+
{
|
|
39
|
+
sort: "id",
|
|
40
|
+
filter: {
|
|
41
|
+
id: props.reportId,
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
);
|
|
45
|
+
report = (await reportsResponse.json()).data[0];
|
|
46
|
+
const chartsResponse = await props.utils.lobb.findAll(
|
|
47
|
+
"reports_charts",
|
|
48
|
+
{
|
|
49
|
+
filter: {
|
|
50
|
+
report_id: report.id,
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
);
|
|
54
|
+
return (await chartsResponse.json()).data;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async function reloadChart() {
|
|
58
|
+
chartsPromise = new Promise(() => {});
|
|
59
|
+
chartsPromise = Promise.resolve(await getCharts());
|
|
60
|
+
}
|
|
61
|
+
</script>
|
|
62
|
+
|
|
63
|
+
<div class="gridContainer relative h-full w-full flex-col overflow-auto">
|
|
64
|
+
{#await chartsPromise}
|
|
65
|
+
<div
|
|
66
|
+
class="flex flex-col gap-4 h-full w-full absolute justify-center items-center"
|
|
67
|
+
>
|
|
68
|
+
<Icons.LoaderCircle class="animate-spin opacity-50" size="50" />
|
|
69
|
+
<div class="flex flex-col items-center justify-center">
|
|
70
|
+
<div class="text-muted-foreground">
|
|
71
|
+
Loading the dashboard...
|
|
72
|
+
</div>
|
|
73
|
+
<div class="text-muted-foreground text-xs">
|
|
74
|
+
Loading all the charts of the selected dashboard
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
{:then charts}
|
|
79
|
+
<div
|
|
80
|
+
class="flex justify-between gap-2 overflow-auto border-b bg-background p-2"
|
|
81
|
+
>
|
|
82
|
+
<div class="flex gap-2">
|
|
83
|
+
<div class="mt-1">
|
|
84
|
+
<SidebarTrigger />
|
|
85
|
+
</div>
|
|
86
|
+
<div class="flex flex-col justify-center">
|
|
87
|
+
<h2 class="font-medium text-primary">{report.name}</h2>
|
|
88
|
+
<div class="text-xs text-muted-foreground">
|
|
89
|
+
{report.description}
|
|
90
|
+
</div>
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
<div class="flex gap-2 self-end">
|
|
94
|
+
<RangeCalendarButton bind:value={dateRangeValue} />
|
|
95
|
+
<CreateDetailViewButton
|
|
96
|
+
collectionName="reports_charts"
|
|
97
|
+
values={{
|
|
98
|
+
report_id: {
|
|
99
|
+
id: props.reportId,
|
|
100
|
+
name: report.name,
|
|
101
|
+
},
|
|
102
|
+
}}
|
|
103
|
+
variant="default"
|
|
104
|
+
class="h-7 px-3 text-xs font-normal"
|
|
105
|
+
Icon={Icons.Plus}
|
|
106
|
+
onSuccessfullSave={async () => await reloadChart()}
|
|
107
|
+
>
|
|
108
|
+
Create chart
|
|
109
|
+
</CreateDetailViewButton>
|
|
110
|
+
</div>
|
|
111
|
+
</div>
|
|
112
|
+
<div class="overflow-auto">
|
|
113
|
+
<div class="chartsGridContainer w-full flex-wrap gap-4 p-4">
|
|
114
|
+
{#if charts.length === 0}
|
|
115
|
+
<div
|
|
116
|
+
class="flex w-full flex-col items-center justify-center gap-4 p-10 text-muted-foreground"
|
|
117
|
+
>
|
|
118
|
+
<Icons.CircleSlash2 class="opacity-50" size="50" />
|
|
119
|
+
<div class="flex flex-col items-center justify-center">
|
|
120
|
+
<div>No charts available</div>
|
|
121
|
+
<div class="text-xs">
|
|
122
|
+
Create a new chart to fill this report page
|
|
123
|
+
</div>
|
|
124
|
+
</div>
|
|
125
|
+
</div>
|
|
126
|
+
{:else}
|
|
127
|
+
{#each charts as chart}
|
|
128
|
+
{#key context}
|
|
129
|
+
<Chart
|
|
130
|
+
chartRecord={chart}
|
|
131
|
+
onChartDeleted={async () => await reloadChart()}
|
|
132
|
+
onChartEdited={async () => await reloadChart()}
|
|
133
|
+
{context}
|
|
134
|
+
{...props}
|
|
135
|
+
/>
|
|
136
|
+
{/key}
|
|
137
|
+
{/each}
|
|
138
|
+
{/if}
|
|
139
|
+
</div>
|
|
140
|
+
</div>
|
|
141
|
+
{/await}
|
|
142
|
+
</div>
|
|
143
|
+
|
|
144
|
+
<style>
|
|
145
|
+
.gridContainer {
|
|
146
|
+
display: grid;
|
|
147
|
+
grid-template-columns: 1fr;
|
|
148
|
+
grid-template-rows: auto 1fr;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.chartsGridContainer {
|
|
152
|
+
display: grid;
|
|
153
|
+
grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
|
|
154
|
+
grid-gap: 10px;
|
|
155
|
+
}
|
|
156
|
+
</style>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
declare const __propDef: {
|
|
3
|
+
props: Record<string, never>;
|
|
4
|
+
events: {
|
|
5
|
+
[evt: string]: CustomEvent<any>;
|
|
6
|
+
};
|
|
7
|
+
slots: {};
|
|
8
|
+
};
|
|
9
|
+
export type ReportProps = typeof __propDef.props;
|
|
10
|
+
export type ReportEvents = typeof __propDef.events;
|
|
11
|
+
export type ReportSlots = typeof __propDef.slots;
|
|
12
|
+
export default class Report extends SvelteComponentTyped<ReportProps, ReportEvents, ReportSlots> {
|
|
13
|
+
}
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { ExtensionProps } from "@lobb-js/studio";
|
|
3
|
+
import type { Location } from "@wjfe/n-savant";
|
|
4
|
+
import Report from "./components/report.svelte";
|
|
5
|
+
|
|
6
|
+
const { utils, ...props }: ExtensionProps = $props();
|
|
7
|
+
|
|
8
|
+
let extensionPagePath = "/studio/extensions/reports/analytics";
|
|
9
|
+
let reportId: string | null = $derived(getReportID(utils.location));
|
|
10
|
+
let sideBarData: any = $state(null);
|
|
11
|
+
const {
|
|
12
|
+
CreateDetailViewButton,
|
|
13
|
+
UpdateDetailViewButton,
|
|
14
|
+
Sidebar,
|
|
15
|
+
SidebarTrigger,
|
|
16
|
+
Button,
|
|
17
|
+
} = utils.components;
|
|
18
|
+
const icons = utils.components.Icons;
|
|
19
|
+
|
|
20
|
+
getSideBarData();
|
|
21
|
+
|
|
22
|
+
async function getSideBarData(): Promise<void> {
|
|
23
|
+
const response = await utils.lobb.findAll("reports_dashboards", {
|
|
24
|
+
sort: "id",
|
|
25
|
+
filter: {},
|
|
26
|
+
});
|
|
27
|
+
const allReports = (await response.json()).data;
|
|
28
|
+
|
|
29
|
+
const localSideBarData: any = [];
|
|
30
|
+
for (let index = 0; index < allReports.length; index++) {
|
|
31
|
+
const report = allReports[index];
|
|
32
|
+
localSideBarData.push({
|
|
33
|
+
name: report.name,
|
|
34
|
+
icon: icons.FileChartColumn,
|
|
35
|
+
onclick: () => {
|
|
36
|
+
utils.location.navigate(
|
|
37
|
+
`${extensionPagePath}/${report.id}`,
|
|
38
|
+
);
|
|
39
|
+
},
|
|
40
|
+
meta: {
|
|
41
|
+
reportId: report.id,
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
sideBarData = localSideBarData;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async function handleReportDelete(recordId: any) {
|
|
50
|
+
const result = await utils.showDialog(
|
|
51
|
+
"Are you sure?",
|
|
52
|
+
"This will delete the report you selected.",
|
|
53
|
+
);
|
|
54
|
+
if (result) {
|
|
55
|
+
await utils.lobb.deleteOne("reports_dashboards", recordId);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function getReportID(location: Location) {
|
|
60
|
+
return location.url.pathname.split("/")[5];
|
|
61
|
+
}
|
|
62
|
+
</script>
|
|
63
|
+
|
|
64
|
+
<Sidebar title="Reports" data={sideBarData}>
|
|
65
|
+
{#snippet belowSearch()}
|
|
66
|
+
<div class="p-2 pb-0">
|
|
67
|
+
<CreateDetailViewButton
|
|
68
|
+
collectionName="reports_dashboards"
|
|
69
|
+
variant="outline"
|
|
70
|
+
class="h-7 w-full px-3 text-xs font-normal"
|
|
71
|
+
Icon={icons.Plus}
|
|
72
|
+
onSuccessfullSave={async (record: any) => {
|
|
73
|
+
await getSideBarData();
|
|
74
|
+
reportId = record.id;
|
|
75
|
+
}}
|
|
76
|
+
>
|
|
77
|
+
Create a report
|
|
78
|
+
</CreateDetailViewButton>
|
|
79
|
+
</div>
|
|
80
|
+
{/snippet}
|
|
81
|
+
{#snippet elementRightSide(item: any)}
|
|
82
|
+
{#if item.meta}
|
|
83
|
+
{@const reportId = item.meta.reportId}
|
|
84
|
+
<div>
|
|
85
|
+
<UpdateDetailViewButton
|
|
86
|
+
collectionName="reports_dashboards"
|
|
87
|
+
recordId={reportId}
|
|
88
|
+
variant="ghost"
|
|
89
|
+
class="h-6 w-6 text-muted-foreground hover:bg-transparent"
|
|
90
|
+
Icon={icons.Pencil}
|
|
91
|
+
onSuccessfullSave={async () => {
|
|
92
|
+
await getSideBarData();
|
|
93
|
+
}}
|
|
94
|
+
></UpdateDetailViewButton>
|
|
95
|
+
<Button
|
|
96
|
+
class="h-6 w-6 text-muted-foreground hover:bg-transparent"
|
|
97
|
+
variant="ghost"
|
|
98
|
+
size="icon"
|
|
99
|
+
Icon={icons.Trash}
|
|
100
|
+
onclick={async () => {
|
|
101
|
+
await handleReportDelete(reportId);
|
|
102
|
+
await getSideBarData();
|
|
103
|
+
}}
|
|
104
|
+
></Button>
|
|
105
|
+
</div>
|
|
106
|
+
{/if}
|
|
107
|
+
{/snippet}
|
|
108
|
+
<div class="relative h-full w-full bg-muted">
|
|
109
|
+
{#if reportId}
|
|
110
|
+
{#key reportId}
|
|
111
|
+
<Report {utils} {reportId} {...props} />
|
|
112
|
+
{/key}
|
|
113
|
+
{:else}
|
|
114
|
+
<div
|
|
115
|
+
class="flex h-full w-full flex-col items-center justify-center gap-4 text-muted-foreground"
|
|
116
|
+
>
|
|
117
|
+
<icons.CircleSlash2 class="opacity-50" size="50" />
|
|
118
|
+
<div class="flex flex-col items-center justify-center">
|
|
119
|
+
<div>No report selected</div>
|
|
120
|
+
<div class="text-xs">
|
|
121
|
+
Please select a report to view the details or create a
|
|
122
|
+
new one
|
|
123
|
+
</div>
|
|
124
|
+
</div>
|
|
125
|
+
<CreateDetailViewButton
|
|
126
|
+
collectionName="reports_dashboards"
|
|
127
|
+
variant="default"
|
|
128
|
+
class="h-7 px-3 text-xs font-normal"
|
|
129
|
+
Icon={icons.Plus}
|
|
130
|
+
onSuccessfullSave={async (record: any) =>
|
|
131
|
+
utils.location.navigate(`?report=${record.id}`)}
|
|
132
|
+
>
|
|
133
|
+
Create a report
|
|
134
|
+
</CreateDetailViewButton>
|
|
135
|
+
</div>
|
|
136
|
+
<div class="absolute top-0 left-0 p-2.5">
|
|
137
|
+
<SidebarTrigger />
|
|
138
|
+
</div>
|
|
139
|
+
{/if}
|
|
140
|
+
</div>
|
|
141
|
+
</Sidebar>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
declare const __propDef: {
|
|
3
|
+
props: Record<string, never>;
|
|
4
|
+
events: {
|
|
5
|
+
[evt: string]: CustomEvent<any>;
|
|
6
|
+
};
|
|
7
|
+
slots: {};
|
|
8
|
+
};
|
|
9
|
+
export type IndexProps = typeof __propDef.props;
|
|
10
|
+
export type IndexEvents = typeof __propDef.events;
|
|
11
|
+
export type IndexSlots = typeof __propDef.slots;
|
|
12
|
+
export default class Index extends SvelteComponentTyped<IndexProps, IndexEvents, IndexSlots> {
|
|
13
|
+
}
|
|
14
|
+
export {};
|
|
File without changes
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type ClassValue } from "clsx";
|
|
2
|
+
export declare function cn(...inputs: ClassValue[]): string;
|
|
3
|
+
export type WithoutChild<T> = T extends {
|
|
4
|
+
child?: any;
|
|
5
|
+
} ? Omit<T, "child"> : T;
|
|
6
|
+
export type WithoutChildren<T> = T extends {
|
|
7
|
+
children?: any;
|
|
8
|
+
} ? Omit<T, "children"> : T;
|
|
9
|
+
export type WithoutChildrenOrChild<T> = WithoutChildren<WithoutChild<T>>;
|
|
10
|
+
export type WithElementRef<T, U extends HTMLElement = HTMLElement> = T & {
|
|
11
|
+
ref?: U | null;
|
|
12
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { test, expect } from "@playwright/test";
|
|
2
|
+
const ANALYTICS_URL = "/studio/extensions/reports/analytics";
|
|
3
|
+
test.describe("Analytics page", () => {
|
|
4
|
+
test.beforeEach(async ({ page }) => {
|
|
5
|
+
await page.goto(ANALYTICS_URL);
|
|
6
|
+
});
|
|
7
|
+
test("shows the analytics page", async ({ page }) => {
|
|
8
|
+
await expect(page).toHaveURL(new RegExp(ANALYTICS_URL));
|
|
9
|
+
});
|
|
10
|
+
test("shows empty state when no report is selected", async ({ page }) => {
|
|
11
|
+
await expect(page.getByText("No report selected")).toBeVisible();
|
|
12
|
+
await expect(page.getByText("Please select a report to view the details or create a new one")).toBeVisible();
|
|
13
|
+
});
|
|
14
|
+
test("shows create a report button in empty state", async ({ page }) => {
|
|
15
|
+
await expect(page.getByRole("button", { name: "Create a report" }).first()).toBeVisible();
|
|
16
|
+
});
|
|
17
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type": "commonjs"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const { defineConfig, devices } = require("@playwright/test");
|
|
2
|
+
|
|
3
|
+
module.exports = defineConfig({
|
|
4
|
+
testDir: __dirname,
|
|
5
|
+
testMatch: "**/*.spec.ts",
|
|
6
|
+
fullyParallel: true,
|
|
7
|
+
retries: 0,
|
|
8
|
+
expect: { timeout: 15000 },
|
|
9
|
+
use: {
|
|
10
|
+
baseURL: "http://localhost:3000",
|
|
11
|
+
trace: "on-first-retry",
|
|
12
|
+
headless: true,
|
|
13
|
+
},
|
|
14
|
+
projects: [
|
|
15
|
+
{
|
|
16
|
+
name: "chromium",
|
|
17
|
+
use: { ...devices["Desktop Chrome"] },
|
|
18
|
+
},
|
|
19
|
+
],
|
|
20
|
+
// Automatically start the dev server before running tests
|
|
21
|
+
webServer: {
|
|
22
|
+
command: "bun run dev",
|
|
23
|
+
url: "http://localhost:3000/studio",
|
|
24
|
+
reuseExistingServer: true,
|
|
25
|
+
cwd: "../../../../", // packages/reports-ext root
|
|
26
|
+
},
|
|
27
|
+
});
|
package/package.json
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobb-js/lobb-ext-reports",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"license": "AGPL-3.0-only",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
8
8
|
},
|
|
9
|
+
"files": [
|
|
10
|
+
"extensions",
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
9
13
|
"exports": {
|
|
10
14
|
".": "./extensions/reports/index.ts",
|
|
11
15
|
"./studio": {
|
|
@@ -19,7 +23,7 @@
|
|
|
19
23
|
"test:studio": "bun --bun playwright test --config extensions/reports/studio/tests/playwright.config.cjs",
|
|
20
24
|
"postinstall": "bun --bun playwright install chromium",
|
|
21
25
|
"dev": "bun run lobb.ts",
|
|
22
|
-
"start": "
|
|
26
|
+
"start": "bun run lobb.ts",
|
|
23
27
|
"prepare": "svelte-kit sync || echo ''",
|
|
24
28
|
"preview": "vite preview",
|
|
25
29
|
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
|
@@ -30,7 +34,7 @@
|
|
|
30
34
|
"build:studio": "vite build"
|
|
31
35
|
},
|
|
32
36
|
"dependencies": {
|
|
33
|
-
"@lobb-js/core": "^0.
|
|
37
|
+
"@lobb-js/core": "^0.14.0",
|
|
34
38
|
"chart.js": "^4.4.8",
|
|
35
39
|
"hono": "^4.7.0",
|
|
36
40
|
"lodash-es": "^4.17.21",
|
|
@@ -39,7 +43,7 @@
|
|
|
39
43
|
"devDependencies": {
|
|
40
44
|
"@faker-js/faker": "^9.6.0",
|
|
41
45
|
"@playwright/test": "^1.58.2",
|
|
42
|
-
"@lobb-js/studio": "^0.
|
|
46
|
+
"@lobb-js/studio": "^0.8.0",
|
|
43
47
|
"@lucide/svelte": "^0.563.1",
|
|
44
48
|
"@sveltejs/adapter-node": "^5.5.4",
|
|
45
49
|
"@sveltejs/kit": "^2.55.0",
|
package/.dockerignore
DELETED
package/.env.example
DELETED
package/.vscode/settings.json
DELETED
package/CHANGELOG.md
DELETED
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
All notable changes to this project will be documented in this file. See [conventional commits](https://www.conventionalcommits.org/) for commit guidelines.
|
|
3
|
-
|
|
4
|
-
- - -
|
|
5
|
-
## reports-ext@0.3.2 - 2026-03-28
|
|
6
|
-
#### Bug Fixes
|
|
7
|
-
- update readme to trigger publish - (cf1e896) - malik ben
|
|
8
|
-
- update READMEs to trigger republish of all packages - (2bd145d) - malik ben
|
|
9
|
-
#### Miscellaneous Chores
|
|
10
|
-
- (**version**) 0.26.2 - (1907933) - Cocogitto Bot
|
|
11
|
-
|
|
12
|
-
- - -
|
|
13
|
-
|
|
14
|
-
## reports-ext@0.3.1 - 2026-03-28
|
|
15
|
-
#### Bug Fixes
|
|
16
|
-
- adding readme to all packages - (3a9264a) - malik ben
|
|
17
|
-
#### Miscellaneous Chores
|
|
18
|
-
- add publishConfig and fix ext packages for npm publishing - (49747e9) - malik ben
|
|
19
|
-
|
|
20
|
-
- - -
|
|
21
|
-
|
|
22
|
-
## reports-ext@0.3.0 - 2026-03-28
|
|
23
|
-
#### Features
|
|
24
|
-
- (**reports-ext**) migrate to Bun - (3d9f927) - malik ben
|
|
25
|
-
- (**reports-ext,storage-ext**) convert studio from Svelte SPA to SvelteKit - (3cd7f63) - malik ben
|
|
26
|
-
- replace hasDashboardExtension with virtual:lobb-studio-extensions module - (437cb2e) - malik ben
|
|
27
|
-
#### Bug Fixes
|
|
28
|
-
- add /studio subpath exports to ext packages, update studio pages to use them - (c0b9a82) - malik ben
|
|
29
|
-
- untrack .svelte-kit from mindhar, fix process leak and $lib imports, update ai sdk versions - (017f784) - malik ben
|
|
30
|
-
- chaning $lib to relative path - (c6d9e8f) - malik ben
|
|
31
|
-
#### Miscellaneous Chores
|
|
32
|
-
- (**reports-ext**) move extension logic and tests to extensions/reports, flatten studio, add Playwright tests - (f814cbf) - malik ben
|
|
33
|
-
- (**version**) 0.25.2 - (a62acb9) - Cocogitto Bot
|
|
34
|
-
- (**version**) 0.25.1 - (afe7e69) - Cocogitto Bot
|
|
35
|
-
- (**version**) 0.25.0 - (77a383c) - Cocogitto Bot
|
|
36
|
-
- (**version**) 0.24.0 - (a8cb605) - Cocogitto Bot
|
|
37
|
-
- (**version**) 0.23.0 - (60f357e) - Cocogitto Bot
|
|
38
|
-
- (**version**) 0.22.0 - (6510e32) - Cocogitto Bot
|
|
39
|
-
- (**version**) 0.21.0 - (c973aa9) - Cocogitto Bot
|
|
40
|
-
- (**version**) 0.20.0 - (06cc303) - Cocogitto Bot
|
|
41
|
-
- add dev:studio/build:studio scripts, fix Dockerfiles, remove --build flag - (1595975) - malik ben
|
|
42
|
-
- add prepublish/postpublish scripts to extension packages for standalone compatibility - (4d6108f) - malik ben
|
|
43
|
-
- centralize studio app.css in @lobb-js/studio package, remove local copies - (05192dc) - malik ben
|
|
44
|
-
- rename @lobb/ scope to @lobb-js/ across all packages and apps - (cce4ce0) - malik ben
|
|
45
|
-
- add start/build scripts and gitignore build dir across all projects - (58f539d) - malik ben
|
|
46
|
-
- update CLAUDE.md to enforce no-commit-without-explicit-instruction rule - (6d63a42) - malik ben
|
|
47
|
-
- remove all deno.json and deno.lock files from the monorepo - (84ca5d4) - malik ben
|
|
48
|
-
- replace workspace:* with exact versions in all package.json files - (74fbdb7) - malik ben
|
|
49
|
-
- rename __studio to studio and remove unused studio dirs - (77fb932) - malik ben
|
|
50
|
-
- rename studio directory to __studio for faker-ext, llm-ext, mail-ext, reports-ext, storage-ext - (47e754a) - malik ben
|
|
51
|
-
- bump deno docker image to 2.6.6 across all Dockerfiles - (a2865b4) - malik ben
|
|
52
|
-
|
|
53
|
-
- - -
|
|
54
|
-
|
|
55
|
-
## reports-ext@0.2.0 - 2026-03-01
|
|
56
|
-
#### Features
|
|
57
|
-
- (**mindhar**) add storage extension integration - (bca6368) - malik ben
|
|
58
|
-
#### Miscellaneous Chores
|
|
59
|
-
- (**version**) 0.18.0 - (efc553f) - Cocogitto Bot
|
|
60
|
-
- (**version**) 0.17.0 - (4174f0c) - Cocogitto Bot
|
|
61
|
-
- (**version**) 0.16.0 - (9508655) - Cocogitto Bot
|
|
62
|
-
- (**version**) 0.14.11 - (ad92b61) - Cocogitto Bot
|
|
63
|
-
- (**version**) 0.14.8 - (0e6c1cb) - Cocogitto Bot
|
|
64
|
-
|
|
65
|
-
- - -
|
|
66
|
-
|
|
67
|
-
## reports-ext@0.1.34 - 2026-02-22
|
|
68
|
-
#### Bug Fixes
|
|
69
|
-
- coggito publishing packages order fix - (573c75e) - malik ben
|
|
70
|
-
#### Miscellaneous Chores
|
|
71
|
-
- (**version**) 0.14.3 - (76abe92) - Cocogitto Bot
|
|
72
|
-
|
|
73
|
-
- - -
|
|
74
|
-
|
|
75
|
-
## reports-ext@0.1.33 - 2026-02-22
|
|
76
|
-
#### Bug Fixes
|
|
77
|
-
- made the collectionService become an property in the main lobb object - (146e4cb) - malik ben
|
|
78
|
-
|
|
79
|
-
- - -
|
|
80
|
-
|
|
81
|
-
## reports-ext@0.1.32 - 2026-02-21
|
|
82
|
-
#### Bug Fixes
|
|
83
|
-
- using default export instead of named export for extensions - (37dd485) - malik ben
|
|
84
|
-
#### Refactoring
|
|
85
|
-
- moving ui_input into the ui property of the field - (8a9edf0) - Malik Najjar
|
|
86
|
-
|
|
87
|
-
- - -
|
|
88
|
-
|
|
89
|
-
## reports-ext@0.1.31 - 2026-02-20
|
|
90
|
-
#### Bug Fixes
|
|
91
|
-
- fix reports extension race condition - (6dd72ba) - Malik Najjar
|
|
92
|
-
#### Miscellaneous Chores
|
|
93
|
-
- (**version**) 0.13.2 - (39b0145) - Cocogitto Bot
|
|
94
|
-
|
|
95
|
-
- - -
|
|
96
|
-
|
|
97
|
-
## reports-ext@0.1.30 - 2026-02-19
|
|
98
|
-
#### Bug Fixes
|
|
99
|
-
- concurent racing fix - (0eeda5f) - malik ben
|
|
100
|
-
|
|
101
|
-
- - -
|
|
102
|
-
|
|
103
|
-
## reports-ext@0.1.29 - 2026-02-19
|
|
104
|
-
#### Bug Fixes
|
|
105
|
-
- adding testing logs - (69ab047) - malik ben
|
|
106
|
-
#### Miscellaneous Chores
|
|
107
|
-
- (**version**) 0.12.3 - (cd06fc0) - Cocogitto Bot
|
|
108
|
-
- (**version**) 0.12.2 - (35b2ff3) - Cocogitto Bot
|
|
109
|
-
- (**version**) 0.12.1 - (c548105) - Cocogitto Bot
|
|
110
|
-
- adding testing logs - (ef42d92) - malik ben
|
|
111
|
-
|
|
112
|
-
- - -
|
|
113
|
-
|
|
114
|
-
## reports-ext@0.1.28 - 2026-02-19
|
|
115
|
-
#### Bug Fixes
|
|
116
|
-
- making the reports work - (1b87561) - Malik Najjar
|
|
117
|
-
#### Miscellaneous Chores
|
|
118
|
-
- (**version**) 0.11.1 - (659ebd3) - Cocogitto Bot
|
|
119
|
-
- (**version**) 0.11.0 - (3f4f47e) - Cocogitto Bot
|
|
120
|
-
- (**version**) 0.10.0 - (5d79b6e) - Cocogitto Bot
|
|
121
|
-
- (**version**) 0.8.0 - (fdee7ca) - Cocogitto Bot
|
|
122
|
-
|
|
123
|
-
- - -
|
|
124
|
-
|
|
125
|
-
## reports-ext@0.1.27 - 2026-02-15
|
|
126
|
-
#### Bug Fixes
|
|
127
|
-
- fix deno publish issue - (e8dcc4f) - malik ben
|
|
128
|
-
- issue fix - (63d66d3) - malik ben
|
|
129
|
-
#### Miscellaneous Chores
|
|
130
|
-
- (**version**) 0.5.5 - (d4dedeb) - Cocogitto Bot
|
|
131
|
-
- (**version**) 0.5.4 - (1ca3970) - Cocogitto Bot
|
|
132
|
-
- (**version**) 0.5.3 - (dcdb9cb) - Cocogitto Bot
|
|
133
|
-
- (**version**) 0.5.2 - (aa66e29) - Cocogitto Bot
|
|
134
|
-
- (**version**) 0.5.1 - (41b7c35) - Cocogitto Bot
|
|
135
|
-
- (**version**) 0.5.0 - (af63147) - Cocogitto Bot
|
|
136
|
-
- (**version**) 0.4.4 - (eaed3b4) - Cocogitto Bot
|
|
137
|
-
- (**version**) 0.4.3 - (ea9ec49) - Cocogitto Bot
|
|
138
|
-
|
|
139
|
-
- - -
|
|
140
|
-
|
|
141
|
-
Changelog generated by [cocogitto](https://github.com/cocogitto/cocogitto).
|
package/lobb.ts
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { Lobb } from "@lobb-js/core";
|
|
2
|
-
import { extension } from "./extensions/reports/index.ts";
|
|
3
|
-
|
|
4
|
-
Lobb.init({
|
|
5
|
-
project: {
|
|
6
|
-
name: "Reports Extension Test",
|
|
7
|
-
force_sync: true,
|
|
8
|
-
},
|
|
9
|
-
database: {
|
|
10
|
-
host: "localhost",
|
|
11
|
-
port: 5432,
|
|
12
|
-
username: "test",
|
|
13
|
-
password: "test",
|
|
14
|
-
database: "reports_ext_dev",
|
|
15
|
-
},
|
|
16
|
-
web_server: {
|
|
17
|
-
host: "0.0.0.0",
|
|
18
|
-
port: 3000,
|
|
19
|
-
cors: {
|
|
20
|
-
origin: "*",
|
|
21
|
-
},
|
|
22
|
-
},
|
|
23
|
-
extensions: [
|
|
24
|
-
extension(),
|
|
25
|
-
],
|
|
26
|
-
collections: {
|
|
27
|
-
donations: {
|
|
28
|
-
indexes: {},
|
|
29
|
-
fields: {
|
|
30
|
-
id: {
|
|
31
|
-
type: "integer",
|
|
32
|
-
},
|
|
33
|
-
donor_name: {
|
|
34
|
-
type: "string",
|
|
35
|
-
length: 255,
|
|
36
|
-
validators: {
|
|
37
|
-
required: true,
|
|
38
|
-
},
|
|
39
|
-
},
|
|
40
|
-
amount: {
|
|
41
|
-
type: "decimal",
|
|
42
|
-
validators: {
|
|
43
|
-
required: true,
|
|
44
|
-
},
|
|
45
|
-
},
|
|
46
|
-
created_at: {
|
|
47
|
-
type: "date",
|
|
48
|
-
pre_processors: {
|
|
49
|
-
default: "{{ now }}",
|
|
50
|
-
},
|
|
51
|
-
},
|
|
52
|
-
},
|
|
53
|
-
},
|
|
54
|
-
},
|
|
55
|
-
});
|
package/scripts/postpublish.sh
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
# Postpublish script for @lobb-js/lobb-ext-reports
|
|
4
|
-
# Reverts package.json exports and cleans dist to avoid uncommitted changes
|
|
5
|
-
|
|
6
|
-
echo "📝 Reverting package.json exports to development mode..."
|
|
7
|
-
jq '."exports"["./studio"] = "./extensions/reports/studio/index.ts"' package.json > package.json.tmp && mv package.json.tmp package.json
|
|
8
|
-
|
|
9
|
-
echo "🧹 Cleaning dist directory..."
|
|
10
|
-
rm -rf dist
|
|
11
|
-
|
|
12
|
-
echo "✅ Postpublish complete"
|
package/scripts/prepublish.sh
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
# Prepublish script for @lobb-js/lobb-ext-reports
|
|
4
|
-
# Builds the studio package and updates exports for publishing
|
|
5
|
-
|
|
6
|
-
echo "📦 Building studio package..."
|
|
7
|
-
bun run package
|
|
8
|
-
|
|
9
|
-
if [ $? -ne 0 ]; then
|
|
10
|
-
echo "❌ Build failed"
|
|
11
|
-
exit 1
|
|
12
|
-
fi
|
|
13
|
-
|
|
14
|
-
echo "📝 Updating package.json exports for publishing..."
|
|
15
|
-
jq '."exports"["./studio"] = {"svelte": "./dist/index.js", "types": "./dist/index.d.ts"}' package.json > package.json.tmp && mv package.json.tmp package.json
|
|
16
|
-
|
|
17
|
-
echo "✅ Prepublish complete"
|
package/studio/app.html
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8" />
|
|
5
|
-
<link rel="icon" href="%sveltekit.assets%/vite.svg" />
|
|
6
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
7
|
-
%sveltekit.head%
|
|
8
|
-
</head>
|
|
9
|
-
<body data-sveltekit-preload-data="hover">
|
|
10
|
-
<div style="display: contents">%sveltekit.body%</div>
|
|
11
|
-
</body>
|
|
12
|
-
</html>
|
package/studio/routes/+layout.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export const ssr = false;
|
package/svelte.config.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import adapter from '@sveltejs/adapter-node';
|
|
2
|
-
|
|
3
|
-
/** @type {import('@sveltejs/kit').Config} */
|
|
4
|
-
const config = {
|
|
5
|
-
kit: {
|
|
6
|
-
adapter: adapter(),
|
|
7
|
-
paths: {
|
|
8
|
-
base: '/studio'
|
|
9
|
-
},
|
|
10
|
-
files: {
|
|
11
|
-
lib: 'studio/lib',
|
|
12
|
-
routes: 'studio/routes',
|
|
13
|
-
appTemplate: 'studio/app.html',
|
|
14
|
-
assets: 'public',
|
|
15
|
-
hooks: {
|
|
16
|
-
server: 'studio/hooks.server',
|
|
17
|
-
client: 'studio/hooks.client',
|
|
18
|
-
},
|
|
19
|
-
params: 'studio/params',
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
export default config;
|
package/todo.md
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
# high priority
|
|
2
|
-
|
|
3
|
-
- make it have two collections. `reports` and `charts`
|
|
4
|
-
- create the endpoint that runs the query of the report
|
|
5
|
-
- you would have global configuration that can effect all reports. or local
|
|
6
|
-
configuration that effects a single report
|
|
7
|
-
- there will be a sidebar with created reports. reports is a page that contains
|
|
8
|
-
multiple widgets of reports
|
|
9
|
-
- some widgets can be expanded to see more details and control over it
|
|
10
|
-
- support realtime by specifying a script that implements it efficienlty instead
|
|
11
|
-
of executing the hole query each time
|
package/tsconfig.app.json
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": "@tsconfig/svelte/tsconfig.json",
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
|
5
|
-
"target": "ES2022",
|
|
6
|
-
"useDefineForClassFields": true,
|
|
7
|
-
"module": "ESNext",
|
|
8
|
-
"types": ["svelte", "vite/client"],
|
|
9
|
-
"noEmit": true,
|
|
10
|
-
"allowArbitraryExtensions": true,
|
|
11
|
-
/**
|
|
12
|
-
* Typecheck JS in `.svelte` and `.js` files by default.
|
|
13
|
-
* Disable checkJs if you'd like to use dynamic types in JS.
|
|
14
|
-
* Note that setting allowJs false does not prevent the use
|
|
15
|
-
* of JS in `.svelte` files.
|
|
16
|
-
*/
|
|
17
|
-
"allowJs": true,
|
|
18
|
-
"checkJs": true,
|
|
19
|
-
"moduleDetection": "force",
|
|
20
|
-
"baseUrl": ".",
|
|
21
|
-
"paths": {
|
|
22
|
-
"$lib": ["./studio/lib"],
|
|
23
|
-
"$lib/*": ["./studio/lib/*"]
|
|
24
|
-
}
|
|
25
|
-
},
|
|
26
|
-
"include": ["studio/**/*.ts", "studio/**/*.js", "studio/**/*.svelte"]
|
|
27
|
-
}
|
package/tsconfig.json
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": "./.svelte-kit/tsconfig.json",
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"allowJs": true,
|
|
5
|
-
"checkJs": true,
|
|
6
|
-
"esModuleInterop": true,
|
|
7
|
-
"forceConsistentCasingInFileNames": true,
|
|
8
|
-
"resolveJsonModule": true,
|
|
9
|
-
"skipLibCheck": true,
|
|
10
|
-
"sourceMap": true,
|
|
11
|
-
"strict": true
|
|
12
|
-
}
|
|
13
|
-
}
|
package/tsconfig.node.json
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
|
4
|
-
"target": "ES2023",
|
|
5
|
-
"lib": ["ES2023"],
|
|
6
|
-
"module": "ESNext",
|
|
7
|
-
"types": ["node"],
|
|
8
|
-
"skipLibCheck": true,
|
|
9
|
-
|
|
10
|
-
/* Bundler mode */
|
|
11
|
-
"moduleResolution": "bundler",
|
|
12
|
-
"allowImportingTsExtensions": true,
|
|
13
|
-
"verbatimModuleSyntax": true,
|
|
14
|
-
"moduleDetection": "force",
|
|
15
|
-
"noEmit": true,
|
|
16
|
-
|
|
17
|
-
/* Linting */
|
|
18
|
-
"strict": true,
|
|
19
|
-
"noUnusedLocals": true,
|
|
20
|
-
"noUnusedParameters": true,
|
|
21
|
-
"erasableSyntaxOnly": true,
|
|
22
|
-
"noFallthroughCasesInSwitch": true,
|
|
23
|
-
"noUncheckedSideEffectImports": true
|
|
24
|
-
},
|
|
25
|
-
"include": ["vite.config.ts"]
|
|
26
|
-
}
|
package/vite.config.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { sveltekit } from '@sveltejs/kit/vite';
|
|
2
|
-
import { defineConfig } from 'vite';
|
|
3
|
-
import tailwindcss from "@tailwindcss/vite";
|
|
4
|
-
import { lobbStudioPlugins } from '@lobb-js/studio/vite-plugins';
|
|
5
|
-
|
|
6
|
-
export default defineConfig({
|
|
7
|
-
plugins: [tailwindcss(), sveltekit(), ...lobbStudioPlugins()],
|
|
8
|
-
});
|