@lobb-js/studio 0.7.2 → 0.8.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/package.json +2 -1
- package/src/App.svelte +5 -0
- package/src/app.css +124 -0
- package/src/lib/components/LlmButton.svelte +137 -0
- package/src/lib/components/Studio.svelte +129 -0
- package/src/lib/components/alertView.svelte +20 -0
- package/src/lib/components/breadCrumbs.svelte +60 -0
- package/src/lib/components/codeEditor.svelte +152 -0
- package/src/lib/components/combobox.svelte +92 -0
- package/src/lib/components/confirmationDialog/confirmationDialog.svelte +33 -0
- package/src/lib/components/confirmationDialog/store.svelte.ts +28 -0
- package/src/lib/components/createManyButton.svelte +109 -0
- package/src/lib/components/dataTable/childRecords.svelte +142 -0
- package/src/lib/components/dataTable/dataTable.svelte +225 -0
- package/src/lib/components/dataTable/fieldCell.svelte +77 -0
- package/src/lib/components/dataTable/filter.svelte +284 -0
- package/src/lib/components/dataTable/filterButton.svelte +39 -0
- package/src/lib/components/dataTable/footer.svelte +84 -0
- package/src/lib/components/dataTable/header.svelte +155 -0
- package/src/lib/components/dataTable/sort.svelte +173 -0
- package/src/lib/components/dataTable/sortButton.svelte +36 -0
- package/src/lib/components/dataTable/table.svelte +337 -0
- package/src/lib/components/dataTable/utils.ts +127 -0
- package/src/lib/components/detailView/create/children.svelte +70 -0
- package/src/lib/components/detailView/create/createDetailView.svelte +228 -0
- package/src/lib/components/detailView/create/createDetailViewButton.svelte +37 -0
- package/src/lib/components/detailView/create/createManyView.svelte +252 -0
- package/src/lib/components/detailView/create/subRecords.svelte +50 -0
- package/src/lib/components/detailView/detailViewForm.svelte +104 -0
- package/src/lib/components/detailView/fieldCustomInput.svelte +26 -0
- package/src/lib/components/detailView/fieldInput.svelte +258 -0
- package/src/lib/components/detailView/fieldInputReplacement.svelte +199 -0
- package/src/lib/components/detailView/store.svelte.ts +59 -0
- package/src/lib/components/detailView/update/children.svelte +96 -0
- package/src/lib/components/detailView/update/updateDetailView.svelte +176 -0
- package/src/lib/components/detailView/update/updateDetailViewButton.svelte +56 -0
- package/src/lib/components/detailView/utils.ts +176 -0
- package/src/lib/components/diffViewer.svelte +105 -0
- package/src/lib/components/drawer.svelte +28 -0
- package/src/lib/components/extensionsComponents.svelte +33 -0
- package/src/lib/components/foreingKeyInput.svelte +80 -0
- package/src/lib/components/header.svelte +45 -0
- package/src/lib/components/loadingTypesForMonacoEditor.ts +36 -0
- package/src/lib/components/miniSidebar.svelte +226 -0
- package/src/lib/components/rangeCalendarButton.svelte +257 -0
- package/src/lib/components/richTextEditor.svelte +284 -0
- package/src/lib/components/routes/collections/collection.svelte +57 -0
- package/src/lib/components/routes/collections/collections.svelte +45 -0
- package/src/lib/components/routes/data_model/dataModel.svelte +40 -0
- package/src/lib/components/routes/data_model/flow.css +22 -0
- package/src/lib/components/routes/data_model/flow.svelte +84 -0
- package/src/lib/components/routes/data_model/syncManager.svelte +94 -0
- package/src/lib/components/routes/data_model/utils.ts +35 -0
- package/src/lib/components/routes/extensions/extension.svelte +19 -0
- package/src/lib/components/routes/home.svelte +40 -0
- package/src/lib/components/routes/workflows/workflows.svelte +136 -0
- package/src/lib/components/selectRecord.svelte +130 -0
- package/src/lib/components/setServerPage.svelte +50 -0
- package/src/lib/components/sidebar/index.ts +4 -0
- package/src/lib/components/sidebar/sidebar.svelte +149 -0
- package/src/lib/components/sidebar/sidebarElements.svelte +144 -0
- package/src/lib/components/sidebar/sidebarTrigger.svelte +33 -0
- package/src/lib/components/singletone.svelte +71 -0
- package/src/lib/components/ui/accordion/accordion-content.svelte +22 -0
- package/src/lib/components/ui/accordion/accordion-item.svelte +12 -0
- package/src/lib/components/ui/accordion/accordion-trigger.svelte +31 -0
- package/src/lib/components/ui/accordion/index.ts +17 -0
- package/src/lib/components/ui/alert/alert-description.svelte +16 -0
- package/src/lib/components/ui/alert/alert-title.svelte +24 -0
- package/src/lib/components/ui/alert/alert.svelte +39 -0
- package/src/lib/components/ui/alert/index.ts +14 -0
- package/src/lib/components/ui/alert-dialog/alert-dialog-action.svelte +13 -0
- package/src/lib/components/ui/alert-dialog/alert-dialog-cancel.svelte +17 -0
- package/src/lib/components/ui/alert-dialog/alert-dialog-content.svelte +26 -0
- package/src/lib/components/ui/alert-dialog/alert-dialog-description.svelte +16 -0
- package/src/lib/components/ui/alert-dialog/alert-dialog-footer.svelte +20 -0
- package/src/lib/components/ui/alert-dialog/alert-dialog-header.svelte +20 -0
- package/src/lib/components/ui/alert-dialog/alert-dialog-overlay.svelte +19 -0
- package/src/lib/components/ui/alert-dialog/alert-dialog-title.svelte +18 -0
- package/src/lib/components/ui/alert-dialog/index.ts +40 -0
- package/src/lib/components/ui/breadcrumb/breadcrumb-ellipsis.svelte +23 -0
- package/src/lib/components/ui/breadcrumb/breadcrumb-item.svelte +16 -0
- package/src/lib/components/ui/breadcrumb/breadcrumb-link.svelte +31 -0
- package/src/lib/components/ui/breadcrumb/breadcrumb-list.svelte +23 -0
- package/src/lib/components/ui/breadcrumb/breadcrumb-page.svelte +23 -0
- package/src/lib/components/ui/breadcrumb/breadcrumb-separator.svelte +27 -0
- package/src/lib/components/ui/breadcrumb/breadcrumb.svelte +15 -0
- package/src/lib/components/ui/breadcrumb/index.ts +25 -0
- package/src/lib/components/ui/button/button.svelte +110 -0
- package/src/lib/components/ui/button/index.ts +17 -0
- package/src/lib/components/ui/checkbox/checkbox.svelte +35 -0
- package/src/lib/components/ui/checkbox/index.ts +6 -0
- package/src/lib/components/ui/command/command-dialog.svelte +35 -0
- package/src/lib/components/ui/command/command-empty.svelte +12 -0
- package/src/lib/components/ui/command/command-group.svelte +31 -0
- package/src/lib/components/ui/command/command-input.svelte +25 -0
- package/src/lib/components/ui/command/command-item.svelte +19 -0
- package/src/lib/components/ui/command/command-link-item.svelte +19 -0
- package/src/lib/components/ui/command/command-list.svelte +16 -0
- package/src/lib/components/ui/command/command-separator.svelte +12 -0
- package/src/lib/components/ui/command/command-shortcut.svelte +20 -0
- package/src/lib/components/ui/command/command.svelte +21 -0
- package/src/lib/components/ui/command/index.ts +40 -0
- package/src/lib/components/ui/dialog/dialog-content.svelte +38 -0
- package/src/lib/components/ui/dialog/dialog-description.svelte +16 -0
- package/src/lib/components/ui/dialog/dialog-footer.svelte +20 -0
- package/src/lib/components/ui/dialog/dialog-header.svelte +20 -0
- package/src/lib/components/ui/dialog/dialog-overlay.svelte +19 -0
- package/src/lib/components/ui/dialog/dialog-title.svelte +16 -0
- package/src/lib/components/ui/dialog/index.ts +37 -0
- package/src/lib/components/ui/input/index.ts +7 -0
- package/src/lib/components/ui/input/input.svelte +46 -0
- package/src/lib/components/ui/label/index.ts +7 -0
- package/src/lib/components/ui/label/label.svelte +19 -0
- package/src/lib/components/ui/popover/index.ts +17 -0
- package/src/lib/components/ui/popover/popover-content.svelte +28 -0
- package/src/lib/components/ui/range-calendar/index.ts +30 -0
- package/src/lib/components/ui/range-calendar/range-calendar-cell.svelte +19 -0
- package/src/lib/components/ui/range-calendar/range-calendar-day.svelte +35 -0
- package/src/lib/components/ui/range-calendar/range-calendar-grid-body.svelte +12 -0
- package/src/lib/components/ui/range-calendar/range-calendar-grid-head.svelte +12 -0
- package/src/lib/components/ui/range-calendar/range-calendar-grid-row.svelte +12 -0
- package/src/lib/components/ui/range-calendar/range-calendar-grid.svelte +16 -0
- package/src/lib/components/ui/range-calendar/range-calendar-head-cell.svelte +16 -0
- package/src/lib/components/ui/range-calendar/range-calendar-header.svelte +16 -0
- package/src/lib/components/ui/range-calendar/range-calendar-heading.svelte +16 -0
- package/src/lib/components/ui/range-calendar/range-calendar-months.svelte +20 -0
- package/src/lib/components/ui/range-calendar/range-calendar-next-button.svelte +27 -0
- package/src/lib/components/ui/range-calendar/range-calendar-prev-button.svelte +27 -0
- package/src/lib/components/ui/range-calendar/range-calendar.svelte +57 -0
- package/src/lib/components/ui/select/index.ts +34 -0
- package/src/lib/components/ui/select/select-content.svelte +38 -0
- package/src/lib/components/ui/select/select-group-heading.svelte +16 -0
- package/src/lib/components/ui/select/select-item.svelte +37 -0
- package/src/lib/components/ui/select/select-scroll-down-button.svelte +19 -0
- package/src/lib/components/ui/select/select-scroll-up-button.svelte +19 -0
- package/src/lib/components/ui/select/select-separator.svelte +13 -0
- package/src/lib/components/ui/select/select-trigger.svelte +24 -0
- package/src/lib/components/ui/separator/index.ts +7 -0
- package/src/lib/components/ui/separator/separator.svelte +22 -0
- package/src/lib/components/ui/skeleton/index.ts +7 -0
- package/src/lib/components/ui/skeleton/skeleton.svelte +22 -0
- package/src/lib/components/ui/sonner/index.ts +1 -0
- package/src/lib/components/ui/sonner/sonner.svelte +20 -0
- package/src/lib/components/ui/switch/index.ts +7 -0
- package/src/lib/components/ui/switch/switch.svelte +27 -0
- package/src/lib/components/ui/textarea/index.ts +7 -0
- package/src/lib/components/ui/textarea/textarea.svelte +22 -0
- package/src/lib/components/ui/tooltip/index.ts +18 -0
- package/src/lib/components/ui/tooltip/tooltip-content.svelte +21 -0
- package/src/lib/components/workflowEditor.svelte +188 -0
- package/src/lib/context.ts +22 -0
- package/src/lib/eventSystem.ts +40 -0
- package/src/lib/extensions/extension.types.ts +92 -0
- package/src/lib/extensions/extensionUtils.ts +156 -0
- package/src/lib/index.ts +24 -0
- package/src/lib/store.svelte.ts +13 -0
- package/src/lib/store.types.ts +28 -0
- package/src/lib/utils.ts +68 -0
- package/src/main.ts +18 -0
- package/src/stories/detailView/detailViewForm.stories.svelte +79 -0
- package/src/vite-env.d.ts +2 -0
- package/vite-plugins/index.js +2 -0
- package/vite-plugins/lobb-proxy.js +36 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { WithElementRef, WithoutChildren } from "bits-ui";
|
|
3
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
4
|
+
import { cn } from "../../../utils.js";
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
ref = $bindable(null),
|
|
8
|
+
class: className,
|
|
9
|
+
...restProps
|
|
10
|
+
}: WithoutChildren<
|
|
11
|
+
WithElementRef<HTMLAttributes<HTMLDivElement>>
|
|
12
|
+
> = $props();
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<div
|
|
16
|
+
bind:this={ref}
|
|
17
|
+
class={cn(
|
|
18
|
+
"bg-primary/10 animate-pulse rounded-md",
|
|
19
|
+
className,
|
|
20
|
+
)}
|
|
21
|
+
{...restProps}
|
|
22
|
+
></div>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Toaster } from "./sonner.svelte";
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Toaster as Sonner, type ToasterProps as SonnerProps } from "svelte-sonner";
|
|
3
|
+
import { mode } from "mode-watcher";
|
|
4
|
+
|
|
5
|
+
let { ...restProps }: SonnerProps = $props();
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<Sonner
|
|
9
|
+
theme={$mode}
|
|
10
|
+
class="toaster group"
|
|
11
|
+
toastOptions={{
|
|
12
|
+
classes: {
|
|
13
|
+
toast: "group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border group-[.toaster]:shadow-lg",
|
|
14
|
+
description: "group-[.toast]:text-muted-foreground",
|
|
15
|
+
actionButton: "group-[.toast]:bg-primary group-[.toast]:text-primary-foreground",
|
|
16
|
+
cancelButton: "group-[.toast]:bg-muted group-[.toast]:text-muted-foreground",
|
|
17
|
+
},
|
|
18
|
+
}}
|
|
19
|
+
{...restProps}
|
|
20
|
+
/>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Switch as SwitchPrimitive, type WithoutChildrenOrChild } from "bits-ui";
|
|
3
|
+
import { cn } from "../../../utils.js";
|
|
4
|
+
|
|
5
|
+
let {
|
|
6
|
+
ref = $bindable(null),
|
|
7
|
+
checked = $bindable(false),
|
|
8
|
+
class: className,
|
|
9
|
+
...restProps
|
|
10
|
+
}: WithoutChildrenOrChild<SwitchPrimitive.RootProps> = $props();
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<SwitchPrimitive.Root
|
|
14
|
+
bind:ref
|
|
15
|
+
bind:checked
|
|
16
|
+
class={cn(
|
|
17
|
+
"focus-visible:ring-ring focus-visible:ring-offset-background data-[state=checked]:bg-primary data-[state=unchecked]:bg-input peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
|
18
|
+
className
|
|
19
|
+
)}
|
|
20
|
+
{...restProps}
|
|
21
|
+
>
|
|
22
|
+
<SwitchPrimitive.Thumb
|
|
23
|
+
class={cn(
|
|
24
|
+
"bg-background pointer-events-none block size-4 rounded-full shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0"
|
|
25
|
+
)}
|
|
26
|
+
/>
|
|
27
|
+
</SwitchPrimitive.Root>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { WithElementRef, WithoutChildren } from "bits-ui";
|
|
3
|
+
import type { HTMLTextareaAttributes } from "svelte/elements";
|
|
4
|
+
import { cn } from "../../../utils.js";
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
ref = $bindable(null),
|
|
8
|
+
value = $bindable(),
|
|
9
|
+
class: className,
|
|
10
|
+
...restProps
|
|
11
|
+
}: WithoutChildren<WithElementRef<HTMLTextareaAttributes>> = $props();
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<textarea
|
|
15
|
+
bind:this={ref}
|
|
16
|
+
bind:value
|
|
17
|
+
class={cn(
|
|
18
|
+
"border-input placeholder:text-muted-foreground focus-visible:ring-ring flex min-h-[60px] w-full rounded-md border bg-transparent px-3 py-2 text-base focus-visible:outline-none focus-visible:ring-1 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
19
|
+
className
|
|
20
|
+
)}
|
|
21
|
+
{...restProps}
|
|
22
|
+
></textarea>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Tooltip as TooltipPrimitive } from "bits-ui";
|
|
2
|
+
import Content from "./tooltip-content.svelte";
|
|
3
|
+
|
|
4
|
+
const Root = TooltipPrimitive.Root;
|
|
5
|
+
const Trigger = TooltipPrimitive.Trigger;
|
|
6
|
+
const Provider = TooltipPrimitive.Provider;
|
|
7
|
+
|
|
8
|
+
export {
|
|
9
|
+
Root,
|
|
10
|
+
Trigger,
|
|
11
|
+
Content,
|
|
12
|
+
Provider,
|
|
13
|
+
//
|
|
14
|
+
Root as Tooltip,
|
|
15
|
+
Content as TooltipContent,
|
|
16
|
+
Trigger as TooltipTrigger,
|
|
17
|
+
Provider as TooltipProvider,
|
|
18
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Tooltip as TooltipPrimitive } from "bits-ui";
|
|
3
|
+
import { cn } from "../../../utils.js";
|
|
4
|
+
|
|
5
|
+
let {
|
|
6
|
+
ref = $bindable(null),
|
|
7
|
+
class: className,
|
|
8
|
+
sideOffset = 4,
|
|
9
|
+
...restProps
|
|
10
|
+
}: TooltipPrimitive.ContentProps = $props();
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<TooltipPrimitive.Content
|
|
14
|
+
bind:ref
|
|
15
|
+
{sideOffset}
|
|
16
|
+
class={cn(
|
|
17
|
+
"bg-primary text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 overflow-hidden rounded-md px-3 py-1.5 text-xs",
|
|
18
|
+
className
|
|
19
|
+
)}
|
|
20
|
+
{...restProps}
|
|
21
|
+
/>
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
export interface WorkflowEntry {
|
|
3
|
+
id?: string;
|
|
4
|
+
name: string;
|
|
5
|
+
directory: string;
|
|
6
|
+
event_name: string;
|
|
7
|
+
input_schema?: string;
|
|
8
|
+
output_schema?: string;
|
|
9
|
+
handler?: string;
|
|
10
|
+
}
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<script lang="ts">
|
|
14
|
+
import { getStudioContext } from "../context";
|
|
15
|
+
import CodeEditor from "../components/codeEditor.svelte";
|
|
16
|
+
|
|
17
|
+
const { lobb, ctx } = getStudioContext();
|
|
18
|
+
import Button from "../components/ui/button/button.svelte";
|
|
19
|
+
import Input from "../components/ui/input/input.svelte";
|
|
20
|
+
import { location } from "@wjfe/n-savant";
|
|
21
|
+
import { Edit, Plus } from "lucide-svelte";
|
|
22
|
+
import { toast } from "svelte-sonner";
|
|
23
|
+
import { isEqual } from "lodash";
|
|
24
|
+
|
|
25
|
+
interface Props {
|
|
26
|
+
workflow: WorkflowEntry;
|
|
27
|
+
refreshSidebar: () => Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
let { workflow = $bindable(), refreshSidebar }: Props = $props();
|
|
31
|
+
|
|
32
|
+
let initialWorkflow = $state.snapshot(workflow);
|
|
33
|
+
let workflowHasChanged = $state(false);
|
|
34
|
+
|
|
35
|
+
// track editor change
|
|
36
|
+
$effect(() => {
|
|
37
|
+
const hasChanged = !isEqual(workflow, initialWorkflow);
|
|
38
|
+
workflowHasChanged = hasChanged;
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
$effect(() => {
|
|
42
|
+
handleWorkflowEventChange(workflow.event_name);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
function handleCtrlSave() {
|
|
46
|
+
if (workflow.id) {
|
|
47
|
+
handleUpdateWorkflow();
|
|
48
|
+
} else {
|
|
49
|
+
handleCreateWorkflow();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
let types = $state("");
|
|
54
|
+
let eventsOptions = $derived([
|
|
55
|
+
{
|
|
56
|
+
label: "No Event",
|
|
57
|
+
value: "",
|
|
58
|
+
},
|
|
59
|
+
...ctx.meta.events.map((event) => ({
|
|
60
|
+
label: event.name,
|
|
61
|
+
value: event.name,
|
|
62
|
+
})),
|
|
63
|
+
]);
|
|
64
|
+
|
|
65
|
+
function handleWorkflowEventChange(eventName: WorkflowEntry["event_name"]) {
|
|
66
|
+
setTimeout(() => {
|
|
67
|
+
const event = ctx.meta.events.find(
|
|
68
|
+
(event) => event.name === eventName,
|
|
69
|
+
);
|
|
70
|
+
let localType = "";
|
|
71
|
+
if (event && event.inputSchema) {
|
|
72
|
+
localType += event.inputSchema;
|
|
73
|
+
} else {
|
|
74
|
+
localType += "type Input = unknown;";
|
|
75
|
+
}
|
|
76
|
+
if (ctx.meta.event_context_type) {
|
|
77
|
+
localType += ctx.meta.event_context_type;
|
|
78
|
+
} else {
|
|
79
|
+
localType += "type Context = unknown;";
|
|
80
|
+
}
|
|
81
|
+
if (event && event.outputSchema) {
|
|
82
|
+
localType += event.outputSchema;
|
|
83
|
+
} else {
|
|
84
|
+
localType += "type Output = Promise<unknown>;";
|
|
85
|
+
}
|
|
86
|
+
types = localType;
|
|
87
|
+
}, 100);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async function handleCreateWorkflow() {
|
|
91
|
+
if (!workflow.name) {
|
|
92
|
+
toast.error("You need to specify a workflow name");
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const reponse = await lobb.createOne("core_workflows", workflow);
|
|
97
|
+
const result = await reponse.json();
|
|
98
|
+
const workflowEntry = result.data;
|
|
99
|
+
location.navigate(`/studio/workflows/${workflowEntry.name}`);
|
|
100
|
+
await refreshSidebar();
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async function handleUpdateWorkflow() {
|
|
104
|
+
if (!workflow.id) {
|
|
105
|
+
throw new Error(
|
|
106
|
+
"For some reasont the id of the currentWorkflow doesnt exist",
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
const reponse = await lobb.updateOne("core_workflows", workflow.id, {
|
|
110
|
+
name: workflow.name,
|
|
111
|
+
event_name: workflow.event_name,
|
|
112
|
+
handler: workflow.handler,
|
|
113
|
+
});
|
|
114
|
+
const result = await reponse.json();
|
|
115
|
+
|
|
116
|
+
if (!(reponse.status >= 400)) {
|
|
117
|
+
toast.success("The workflow was updated successfully");
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
workflow = result.data;
|
|
121
|
+
|
|
122
|
+
await refreshSidebar();
|
|
123
|
+
}
|
|
124
|
+
</script>
|
|
125
|
+
|
|
126
|
+
<div class="flex flex-col h-full">
|
|
127
|
+
<div
|
|
128
|
+
class="flex justify-between items-start py-2 pl-9 pr-2 bg-background border-b"
|
|
129
|
+
>
|
|
130
|
+
<div class="flex gap-2 flex-wrap">
|
|
131
|
+
<Input
|
|
132
|
+
bind:value={workflow.name}
|
|
133
|
+
class="h-7 w-48 bg-background"
|
|
134
|
+
placeholder="Workflow name"
|
|
135
|
+
/>
|
|
136
|
+
<Input
|
|
137
|
+
bind:value={workflow.event_name}
|
|
138
|
+
class="h-7 w-48 bg-background"
|
|
139
|
+
placeholder="Workflow event"
|
|
140
|
+
list="events_options"
|
|
141
|
+
/>
|
|
142
|
+
<datalist id="events_options">
|
|
143
|
+
{#each eventsOptions as eventOption}
|
|
144
|
+
<option value={eventOption.value}>
|
|
145
|
+
{eventOption.label}
|
|
146
|
+
</option>
|
|
147
|
+
{/each}
|
|
148
|
+
</datalist>
|
|
149
|
+
<Input
|
|
150
|
+
bind:value={workflow.directory}
|
|
151
|
+
class="h-7 w-48 bg-background"
|
|
152
|
+
placeholder="Workflow directory"
|
|
153
|
+
/>
|
|
154
|
+
</div>
|
|
155
|
+
<div>
|
|
156
|
+
{#if workflow.id}
|
|
157
|
+
<Button
|
|
158
|
+
class="h-7 px-3 text-xs font-normal w-full"
|
|
159
|
+
variant="default"
|
|
160
|
+
onclick={handleUpdateWorkflow}
|
|
161
|
+
Icon={Edit}
|
|
162
|
+
disabled={!workflowHasChanged}
|
|
163
|
+
>
|
|
164
|
+
Save
|
|
165
|
+
</Button>
|
|
166
|
+
{:else}
|
|
167
|
+
<Button
|
|
168
|
+
class="h-7 px-3 text-xs font-normal w-full"
|
|
169
|
+
variant="default"
|
|
170
|
+
onclick={handleCreateWorkflow}
|
|
171
|
+
Icon={Plus}
|
|
172
|
+
>
|
|
173
|
+
Create
|
|
174
|
+
</Button>
|
|
175
|
+
{/if}
|
|
176
|
+
</div>
|
|
177
|
+
</div>
|
|
178
|
+
{#key types}
|
|
179
|
+
<CodeEditor
|
|
180
|
+
type="typescript"
|
|
181
|
+
name="workflow"
|
|
182
|
+
class="h-full rounded-none border-none"
|
|
183
|
+
{types}
|
|
184
|
+
{handleCtrlSave}
|
|
185
|
+
bind:value={workflow.handler}
|
|
186
|
+
/>
|
|
187
|
+
{/key}
|
|
188
|
+
</div>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { setContext, getContext } from 'svelte';
|
|
2
|
+
import type { LobbClient } from '@lobb-js/sdk';
|
|
3
|
+
import type { CTX } from './store.types';
|
|
4
|
+
|
|
5
|
+
export interface StudioContext {
|
|
6
|
+
ctx: CTX;
|
|
7
|
+
lobb: LobbClient;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const STUDIO_CONTEXT_KEY = Symbol('studio');
|
|
11
|
+
|
|
12
|
+
export function setStudioContext(context: StudioContext) {
|
|
13
|
+
setContext(STUDIO_CONTEXT_KEY, context);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function getStudioContext(): StudioContext {
|
|
17
|
+
return getContext(STUDIO_CONTEXT_KEY);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function createStudioContextMap(context: StudioContext): Map<symbol, StudioContext> {
|
|
21
|
+
return new Map([[STUDIO_CONTEXT_KEY, context]]);
|
|
22
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { toast } from "svelte-sonner";
|
|
2
|
+
import type { StudioContext } from "./context";
|
|
3
|
+
import { openCreateDetailView, openUpdateDetailView } from "./components/detailView/store.svelte";
|
|
4
|
+
import type { UpdateDetailViewProp } from "./components/detailView/update/updateDetailView.svelte";
|
|
5
|
+
|
|
6
|
+
export async function emitEvent(studioContext: StudioContext, eventName: string, input: Record<string, any>) {
|
|
7
|
+
const { ctx } = studioContext;
|
|
8
|
+
const workflows = ctx.meta.studio_workflows.filter(
|
|
9
|
+
(workflow) => {
|
|
10
|
+
return eventName.startsWith(workflow.eventName);
|
|
11
|
+
},
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
for (let index = 0; index < workflows.length; index++) {
|
|
15
|
+
const workflow = workflows[index];
|
|
16
|
+
try {
|
|
17
|
+
const localOutput = await workflow.handler(
|
|
18
|
+
input,
|
|
19
|
+
await getEventContext(studioContext),
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
if (localOutput) {
|
|
23
|
+
input = localOutput;
|
|
24
|
+
}
|
|
25
|
+
} catch (error) {
|
|
26
|
+
toast.error((error as any).message);
|
|
27
|
+
throw error;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return input;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async function getEventContext(studioContext: StudioContext) {
|
|
35
|
+
return {
|
|
36
|
+
toast,
|
|
37
|
+
openCreateDetailView: (props: UpdateDetailViewProp) => openCreateDetailView(studioContext, props),
|
|
38
|
+
openUpdateDetailView: (props: UpdateDetailViewProp) => openUpdateDetailView(studioContext, props),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type { LobbClient } from "@lobb-js/sdk";
|
|
2
|
+
import type { CTX } from "../lib/store.types";
|
|
3
|
+
import type { Button } from "../components/ui/button";
|
|
4
|
+
import type { Input } from "../components/ui/input";
|
|
5
|
+
import type { Separator } from "../components/ui/separator";
|
|
6
|
+
import type { Skeleton } from "../components/ui/skeleton";
|
|
7
|
+
import type LlmButton from "../components/LlmButton.svelte";
|
|
8
|
+
import type Sidebar from "../components/sidebar/sidebar.svelte";
|
|
9
|
+
import type SidebarTrigger from "../components/sidebar/sidebarTrigger.svelte";
|
|
10
|
+
import type CreateDetailViewButton from "../components/detailView/create/createDetailViewButton.svelte";
|
|
11
|
+
import type UpdateDetailViewButton from "../components/detailView/update/updateDetailViewButton.svelte";
|
|
12
|
+
import type { mediaQueries } from "../utils";
|
|
13
|
+
import type Table from "../components/dataTable/table.svelte";
|
|
14
|
+
import type { Location } from "@wjfe/n-savant";
|
|
15
|
+
import type RangeCalendarButton from "../components/rangeCalendarButton.svelte";
|
|
16
|
+
import type DataTable from "../components/dataTable/dataTable.svelte";
|
|
17
|
+
import type Drawer from "../components/drawer.svelte";
|
|
18
|
+
import type SelectRecord from "../components/selectRecord.svelte";
|
|
19
|
+
import * as Popover from "../components/ui/popover";
|
|
20
|
+
import * as intlDate from "@internationalized/date";
|
|
21
|
+
import * as Icons from "lucide-svelte"
|
|
22
|
+
import { ContextMenu } from "bits-ui";
|
|
23
|
+
import * as Tooltip from "../components/ui/tooltip";
|
|
24
|
+
import * as Breadcrumb from "../components/ui/breadcrumb";
|
|
25
|
+
import { showDialog } from "../components/confirmationDialog/store.svelte";
|
|
26
|
+
import { toast } from "svelte-sonner";
|
|
27
|
+
import type Drawer from "../components/drawer.svelte";
|
|
28
|
+
import { Switch } from "../components/ui/switch";
|
|
29
|
+
|
|
30
|
+
// extensions utils
|
|
31
|
+
export interface Components {
|
|
32
|
+
Button: typeof Button;
|
|
33
|
+
Input: typeof Input;
|
|
34
|
+
Separator: typeof Separator;
|
|
35
|
+
Skeleton: typeof Skeleton;
|
|
36
|
+
LlmButton: typeof LlmButton;
|
|
37
|
+
Sidebar: typeof Sidebar;
|
|
38
|
+
SidebarTrigger: typeof SidebarTrigger;
|
|
39
|
+
CreateDetailViewButton: typeof CreateDetailViewButton;
|
|
40
|
+
UpdateDetailViewButton: typeof UpdateDetailViewButton;
|
|
41
|
+
Tooltip: typeof Tooltip;
|
|
42
|
+
Breadcrumb: typeof Breadcrumb;
|
|
43
|
+
ContextMenu: typeof ContextMenu;
|
|
44
|
+
Popover: typeof Popover;
|
|
45
|
+
Icons: typeof Icons;
|
|
46
|
+
Table: typeof Table;
|
|
47
|
+
RangeCalendarButton: typeof RangeCalendarButton;
|
|
48
|
+
DataTable: typeof DataTable;
|
|
49
|
+
Drawer: typeof Drawer;
|
|
50
|
+
SelectRecord: typeof SelectRecord,
|
|
51
|
+
Switch: typeof Switch,
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface ExtensionUtils {
|
|
55
|
+
ctx: CTX;
|
|
56
|
+
lobb: LobbClient;
|
|
57
|
+
location: Location;
|
|
58
|
+
toast: typeof toast;
|
|
59
|
+
showDialog: typeof showDialog;
|
|
60
|
+
components: Components;
|
|
61
|
+
mediaQueries: typeof mediaQueries;
|
|
62
|
+
intlDate: typeof intlDate;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// dashboard nav
|
|
66
|
+
interface DashboardNav {
|
|
67
|
+
label: string;
|
|
68
|
+
icon: any;
|
|
69
|
+
href?: string;
|
|
70
|
+
onclick?: () => void;
|
|
71
|
+
navs?: DashboardNav[];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface DashboardNavs {
|
|
75
|
+
top?: DashboardNav[];
|
|
76
|
+
middle?: DashboardNav[];
|
|
77
|
+
bottom?: DashboardNav[];
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// extension components base Props
|
|
81
|
+
export interface ExtensionProps {
|
|
82
|
+
utils: ExtensionUtils;
|
|
83
|
+
[key: string]: any;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// extension exported object
|
|
87
|
+
export interface Extension {
|
|
88
|
+
name: string;
|
|
89
|
+
onStartup?: (utils: ExtensionUtils) => Promise<void>;
|
|
90
|
+
components?: Record<string, any>;
|
|
91
|
+
dashboardNavs?: DashboardNavs;
|
|
92
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Components,
|
|
3
|
+
DashboardNavs,
|
|
4
|
+
Extension,
|
|
5
|
+
ExtensionUtils,
|
|
6
|
+
} from "./extension.types";
|
|
7
|
+
import type { LobbClient } from "@lobb-js/sdk";
|
|
8
|
+
import type { CTX } from "../store.types";
|
|
9
|
+
import { toast } from "svelte-sonner";
|
|
10
|
+
import { showDialog } from "../components/confirmationDialog/store.svelte";
|
|
11
|
+
import { Button } from "../components/ui/button";
|
|
12
|
+
import { Input } from "../components/ui/input";
|
|
13
|
+
import { Separator } from "../components/ui/separator";
|
|
14
|
+
import { Skeleton } from "../components/ui/skeleton";
|
|
15
|
+
import Table from "../components/dataTable/table.svelte";
|
|
16
|
+
import { mediaQueries } from "../utils";
|
|
17
|
+
import LlmButton from "../components/LlmButton.svelte";
|
|
18
|
+
import Sidebar from "../components/sidebar/sidebar.svelte";
|
|
19
|
+
import SidebarTrigger from "../components/sidebar/sidebarTrigger.svelte";
|
|
20
|
+
import CreateDetailViewButton from "../components/detailView/create/createDetailViewButton.svelte";
|
|
21
|
+
import UpdateDetailViewButton from "../components/detailView/update/updateDetailViewButton.svelte";
|
|
22
|
+
import * as intlDate from "@internationalized/date";
|
|
23
|
+
import * as Tooltip from "../components/ui/tooltip";
|
|
24
|
+
import * as Breadcrumb from "../components/ui/breadcrumb";
|
|
25
|
+
import { ContextMenu } from "bits-ui";
|
|
26
|
+
import * as Popover from "../components/ui/popover";
|
|
27
|
+
import * as Icons from "lucide-svelte";
|
|
28
|
+
import { location } from "@wjfe/n-savant";
|
|
29
|
+
import RangeCalendarButton from "../components/rangeCalendarButton.svelte";
|
|
30
|
+
import DataTable from "../components/dataTable/dataTable.svelte";
|
|
31
|
+
import Drawer from "../components/drawer.svelte";
|
|
32
|
+
import SelectRecord from "../components/selectRecord.svelte";
|
|
33
|
+
import { Switch } from "../components/ui/switch";
|
|
34
|
+
|
|
35
|
+
export function getComponents(): Components {
|
|
36
|
+
return {
|
|
37
|
+
Button: Button,
|
|
38
|
+
Input: Input,
|
|
39
|
+
Separator: Separator,
|
|
40
|
+
Skeleton: Skeleton,
|
|
41
|
+
LlmButton: LlmButton,
|
|
42
|
+
Sidebar: Sidebar,
|
|
43
|
+
SidebarTrigger: SidebarTrigger,
|
|
44
|
+
CreateDetailViewButton: CreateDetailViewButton,
|
|
45
|
+
UpdateDetailViewButton: UpdateDetailViewButton,
|
|
46
|
+
Tooltip: Tooltip,
|
|
47
|
+
Breadcrumb: Breadcrumb,
|
|
48
|
+
ContextMenu: ContextMenu,
|
|
49
|
+
Popover: Popover,
|
|
50
|
+
Icons: Icons,
|
|
51
|
+
Table: Table,
|
|
52
|
+
RangeCalendarButton: RangeCalendarButton,
|
|
53
|
+
DataTable: DataTable,
|
|
54
|
+
Drawer: Drawer,
|
|
55
|
+
SelectRecord: SelectRecord,
|
|
56
|
+
Switch: Switch,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function getExtensionUtils(lobb: LobbClient, ctx: CTX): ExtensionUtils {
|
|
61
|
+
return {
|
|
62
|
+
ctx: ctx,
|
|
63
|
+
lobb: lobb,
|
|
64
|
+
location: location,
|
|
65
|
+
toast: toast,
|
|
66
|
+
showDialog: showDialog,
|
|
67
|
+
components: getComponents(),
|
|
68
|
+
mediaQueries: mediaQueries,
|
|
69
|
+
intlDate: intlDate,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export async function loadExtensions(lobb: LobbClient, ctx: CTX, extensionMap: Record<string, any> = {}): Promise<Record<string, Extension>> {
|
|
74
|
+
const extensions: Record<string, Extension> = {};
|
|
75
|
+
|
|
76
|
+
const extensionNames = Object.keys(extensionMap).filter(name => ctx.meta.extensions[name] != null);
|
|
77
|
+
for (let index = 0; index < extensionNames.length; index++) {
|
|
78
|
+
const extensionName = extensionNames[index];
|
|
79
|
+
|
|
80
|
+
const studioExtension = extensionMap[extensionName](getExtensionUtils(lobb, ctx));
|
|
81
|
+
extensions[studioExtension.name] = studioExtension;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return extensions;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function loadExtensionComponents(
|
|
88
|
+
ctx: CTX,
|
|
89
|
+
name: string,
|
|
90
|
+
filterByExtensions?: string[],
|
|
91
|
+
): any[] {
|
|
92
|
+
const components = [];
|
|
93
|
+
for (const [extensionName, extensionValue] of Object.entries(
|
|
94
|
+
ctx.extensions,
|
|
95
|
+
)) {
|
|
96
|
+
if (filterByExtensions && !filterByExtensions.includes(extensionName)) {
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
if (extensionValue.components) {
|
|
100
|
+
for (const [componentName, componentValue] of Object.entries(
|
|
101
|
+
extensionValue.components,
|
|
102
|
+
)) {
|
|
103
|
+
if (name.startsWith(componentName)) {
|
|
104
|
+
components.push(componentValue);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return components;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export async function executeExtensionsOnStartup(lobb: LobbClient, ctx: CTX) {
|
|
113
|
+
const extensionNames: string[] = Object.keys(ctx.extensions);
|
|
114
|
+
for (let index = 0; index < extensionNames.length; index++) {
|
|
115
|
+
const extensionName = extensionNames[index];
|
|
116
|
+
const extension = ctx.extensions[extensionName];
|
|
117
|
+
if (extension) {
|
|
118
|
+
if (extension.onStartup) {
|
|
119
|
+
await extension.onStartup(getExtensionUtils(lobb, ctx));
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export function getDashboardNavs(ctx: CTX): DashboardNavs {
|
|
126
|
+
let navs: DashboardNavs = {
|
|
127
|
+
top: [],
|
|
128
|
+
middle: [],
|
|
129
|
+
bottom: [],
|
|
130
|
+
};
|
|
131
|
+
const extensionNames: string[] = Object.keys(ctx.extensions);
|
|
132
|
+
for (let index = 0; index < extensionNames.length; index++) {
|
|
133
|
+
const extensionName = extensionNames[index];
|
|
134
|
+
const extension = ctx.extensions[extensionName];
|
|
135
|
+
if (extension) {
|
|
136
|
+
if (extension.dashboardNavs && extension.dashboardNavs.top && navs.top) {
|
|
137
|
+
navs.top = [...navs.top, ...extension.dashboardNavs.top];
|
|
138
|
+
}
|
|
139
|
+
if (
|
|
140
|
+
extension.dashboardNavs &&
|
|
141
|
+
extension.dashboardNavs.middle &&
|
|
142
|
+
navs.middle
|
|
143
|
+
) {
|
|
144
|
+
navs.middle = [...navs.middle, ...extension.dashboardNavs.middle];
|
|
145
|
+
}
|
|
146
|
+
if (
|
|
147
|
+
extension.dashboardNavs &&
|
|
148
|
+
extension.dashboardNavs.bottom &&
|
|
149
|
+
navs.bottom
|
|
150
|
+
) {
|
|
151
|
+
navs.bottom = [...navs.bottom, ...extension.dashboardNavs.bottom];
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return navs;
|
|
156
|
+
}
|
package/src/lib/index.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export type { ExtensionProps, Extension, ExtensionUtils } from "./extensions/extension.types"
|
|
2
|
+
|
|
3
|
+
export { default as Studio } from "./components/Studio.svelte";
|
|
4
|
+
export { Button } from "./components/ui/button";
|
|
5
|
+
export { Input } from "./components/ui/input";
|
|
6
|
+
export { Separator } from "./components/ui/separator";
|
|
7
|
+
export { Skeleton } from "./components/ui/skeleton";
|
|
8
|
+
export { default as LlmButton } from "./components/LlmButton.svelte";
|
|
9
|
+
export { default as Sidebar } from "./components/sidebar/sidebar.svelte";
|
|
10
|
+
export { default as SidebarTrigger } from "./components/sidebar/sidebarTrigger.svelte";
|
|
11
|
+
export { default as CreateDetailViewButton } from "./components/detailView/create/createDetailViewButton.svelte";
|
|
12
|
+
export { default as UpdateDetailViewButton } from "./components/detailView/update/updateDetailViewButton.svelte";
|
|
13
|
+
export * as Tooltip from "./components/ui/tooltip";
|
|
14
|
+
export * as Breadcrumb from "./components/ui/breadcrumb";
|
|
15
|
+
export { ContextMenu } from "bits-ui";
|
|
16
|
+
export * as Popover from "./components/ui/popover";
|
|
17
|
+
export * as Icons from "lucide-svelte";
|
|
18
|
+
export * as Dialog from "./components/ui/dialog/index";
|
|
19
|
+
export { default as Table } from "./components/dataTable/table.svelte";
|
|
20
|
+
export { default as RangeCalendarButton } from "./components/rangeCalendarButton.svelte";
|
|
21
|
+
export { default as DataTable } from "./components/dataTable/dataTable.svelte";
|
|
22
|
+
export { default as Drawer } from "./components/drawer.svelte";
|
|
23
|
+
export { default as SelectRecord } from "./components/selectRecord.svelte";
|
|
24
|
+
export { Switch } from "./components/ui/switch";
|