@lobb-js/studio 0.1.31
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/.env.example +1 -0
- package/.storybook/main.ts +31 -0
- package/.storybook/preview.ts +21 -0
- package/.storybook/vitest.setup.ts +7 -0
- package/README.md +47 -0
- package/components.json +16 -0
- package/docker-entrypoint.sh +7 -0
- package/dockerfile +27 -0
- package/index.html +13 -0
- package/package.json +77 -0
- package/public/lobb.svg +15 -0
- package/src/Studio.svelte +150 -0
- package/src/app.css +121 -0
- package/src/components-export.ts +21 -0
- package/src/extensions/extension.types.ts +93 -0
- package/src/extensions/extensionUtils.ts +192 -0
- package/src/lib/Lobb.ts +241 -0
- package/src/lib/components/LlmButton.svelte +136 -0
- package/src/lib/components/alertView.svelte +20 -0
- package/src/lib/components/breadCrumbs.svelte +60 -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 +107 -0
- package/src/lib/components/dataTable/childRecords.svelte +140 -0
- package/src/lib/components/dataTable/dataTable.svelte +223 -0
- package/src/lib/components/dataTable/fieldCell.svelte +74 -0
- package/src/lib/components/dataTable/filter.svelte +282 -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 +154 -0
- package/src/lib/components/dataTable/sort.svelte +171 -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 +68 -0
- package/src/lib/components/detailView/create/createDetailView.svelte +226 -0
- package/src/lib/components/detailView/create/createDetailViewButton.svelte +32 -0
- package/src/lib/components/detailView/create/createManyView.svelte +250 -0
- package/src/lib/components/detailView/create/subRecords.svelte +48 -0
- package/src/lib/components/detailView/detailViewForm.svelte +104 -0
- package/src/lib/components/detailView/fieldCustomInput.svelte +23 -0
- package/src/lib/components/detailView/fieldInput.svelte +287 -0
- package/src/lib/components/detailView/fieldInputReplacement.svelte +199 -0
- package/src/lib/components/detailView/store.svelte.ts +61 -0
- package/src/lib/components/detailView/update/children.svelte +94 -0
- package/src/lib/components/detailView/update/updateDetailView.svelte +175 -0
- package/src/lib/components/detailView/update/updateDetailViewButton.svelte +32 -0
- package/src/lib/components/detailView/utils.ts +177 -0
- package/src/lib/components/diffViewer.svelte +102 -0
- package/src/lib/components/drawer.svelte +28 -0
- package/src/lib/components/extensionsComponents.svelte +31 -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 +238 -0
- package/src/lib/components/monacoEditor.svelte +181 -0
- package/src/lib/components/rangeCalendarButton.svelte +257 -0
- package/src/lib/components/selectRecord.svelte +126 -0
- package/src/lib/components/setServerPage.svelte +48 -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 +69 -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 +187 -0
- package/src/lib/eventSystem.ts +38 -0
- package/src/lib/index.ts +40 -0
- package/src/lib/store.svelte.ts +21 -0
- package/src/lib/store.types.ts +28 -0
- package/src/lib/utils.ts +84 -0
- package/src/main.ts +18 -0
- package/src/routes/collections/collection.svelte +46 -0
- package/src/routes/collections/collections.svelte +43 -0
- package/src/routes/data_model/dataModel.svelte +40 -0
- package/src/routes/data_model/flow.css +22 -0
- package/src/routes/data_model/flow.svelte +82 -0
- package/src/routes/data_model/syncManager.svelte +93 -0
- package/src/routes/data_model/utils.ts +35 -0
- package/src/routes/extensions/extension.svelte +16 -0
- package/src/routes/home.svelte +36 -0
- package/src/routes/workflows/workflows.svelte +135 -0
- package/src/stories/Configure.mdx +364 -0
- package/src/stories/assets/accessibility.png +0 -0
- package/src/stories/assets/accessibility.svg +1 -0
- package/src/stories/assets/addon-library.png +0 -0
- package/src/stories/assets/assets.png +0 -0
- package/src/stories/assets/avif-test-image.avif +0 -0
- package/src/stories/assets/context.png +0 -0
- package/src/stories/assets/discord.svg +1 -0
- package/src/stories/assets/docs.png +0 -0
- package/src/stories/assets/figma-plugin.png +0 -0
- package/src/stories/assets/github.svg +1 -0
- package/src/stories/assets/share.png +0 -0
- package/src/stories/assets/styling.png +0 -0
- package/src/stories/assets/testing.png +0 -0
- package/src/stories/assets/theming.png +0 -0
- package/src/stories/assets/tutorials.svg +1 -0
- package/src/stories/assets/youtube.svg +1 -0
- package/src/stories/detailView/detailViewForm.stories.svelte +79 -0
- package/src/stories/examples/Button.stories.svelte +31 -0
- package/src/stories/examples/Button.svelte +30 -0
- package/src/stories/examples/Header.stories.svelte +26 -0
- package/src/stories/examples/Header.svelte +45 -0
- package/src/stories/examples/Page.stories.svelte +29 -0
- package/src/stories/examples/Page.svelte +70 -0
- package/src/stories/examples/button.css +30 -0
- package/src/stories/examples/header.css +32 -0
- package/src/stories/examples/page.css +68 -0
- package/src/vite-env.d.ts +2 -0
- package/svelte.config.js +7 -0
- package/todo.md +24 -0
- package/tsconfig.app.json +25 -0
- package/tsconfig.json +14 -0
- package/tsconfig.node.json +24 -0
- package/vite-plugin-contextual-lib.js +66 -0
- package/vite.build.svelte.config.ts +18 -0
- package/vite.config.ts +84 -0
- package/vite.extension.config.ts +81 -0
- package/vite_utils.ts +28 -0
- package/vitest.shims.d.ts +1 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Select as SelectPrimitive, type WithoutChild } from "bits-ui";
|
|
3
|
+
import Check from "@lucide/svelte/icons/check";
|
|
4
|
+
import { cn } from "$lib/utils.js";
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
ref = $bindable(null),
|
|
8
|
+
class: className,
|
|
9
|
+
value,
|
|
10
|
+
label,
|
|
11
|
+
children: childrenProp,
|
|
12
|
+
...restProps
|
|
13
|
+
}: WithoutChild<SelectPrimitive.ItemProps> = $props();
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<SelectPrimitive.Item
|
|
17
|
+
bind:ref
|
|
18
|
+
{value}
|
|
19
|
+
class={cn(
|
|
20
|
+
"data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none data-disabled:pointer-events-none data-disabled:opacity-50",
|
|
21
|
+
className
|
|
22
|
+
)}
|
|
23
|
+
{...restProps}
|
|
24
|
+
>
|
|
25
|
+
{#snippet children({ selected, highlighted })}
|
|
26
|
+
<span class="absolute right-2 flex size-3.5 items-center justify-center">
|
|
27
|
+
{#if selected}
|
|
28
|
+
<Check class="size-4" />
|
|
29
|
+
{/if}
|
|
30
|
+
</span>
|
|
31
|
+
{#if childrenProp}
|
|
32
|
+
{@render childrenProp({ selected, highlighted })}
|
|
33
|
+
{:else}
|
|
34
|
+
{label || value}
|
|
35
|
+
{/if}
|
|
36
|
+
{/snippet}
|
|
37
|
+
</SelectPrimitive.Item>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import ChevronDown from "@lucide/svelte/icons/chevron-down";
|
|
3
|
+
import { Select as SelectPrimitive, type WithoutChildrenOrChild } from "bits-ui";
|
|
4
|
+
import { cn } from "$lib/utils.js";
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
ref = $bindable(null),
|
|
8
|
+
class: className,
|
|
9
|
+
...restProps
|
|
10
|
+
}: WithoutChildrenOrChild<SelectPrimitive.ScrollDownButtonProps> = $props();
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<SelectPrimitive.ScrollDownButton
|
|
14
|
+
bind:ref
|
|
15
|
+
class={cn("flex cursor-default items-center justify-center py-1", className)}
|
|
16
|
+
{...restProps}
|
|
17
|
+
>
|
|
18
|
+
<ChevronDown class="size-4" />
|
|
19
|
+
</SelectPrimitive.ScrollDownButton>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import ChevronUp from "@lucide/svelte/icons/chevron-up";
|
|
3
|
+
import { Select as SelectPrimitive, type WithoutChildrenOrChild } from "bits-ui";
|
|
4
|
+
import { cn } from "$lib/utils.js";
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
ref = $bindable(null),
|
|
8
|
+
class: className,
|
|
9
|
+
...restProps
|
|
10
|
+
}: WithoutChildrenOrChild<SelectPrimitive.ScrollDownButtonProps> = $props();
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<SelectPrimitive.ScrollUpButton
|
|
14
|
+
bind:ref
|
|
15
|
+
class={cn("flex cursor-default items-center justify-center py-1", className)}
|
|
16
|
+
{...restProps}
|
|
17
|
+
>
|
|
18
|
+
<ChevronUp class="size-4" />
|
|
19
|
+
</SelectPrimitive.ScrollUpButton>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Separator as SeparatorPrimitive } from "bits-ui";
|
|
3
|
+
import { Separator } from "$lib/components/ui/separator/index.js";
|
|
4
|
+
import { cn } from "$lib/utils.js";
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
ref = $bindable(null),
|
|
8
|
+
class: className,
|
|
9
|
+
...restProps
|
|
10
|
+
}: SeparatorPrimitive.RootProps = $props();
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<Separator bind:ref class={cn("bg-muted -mx-1 my-1 h-px", className)} {...restProps} />
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Select as SelectPrimitive, type WithoutChild } from "bits-ui";
|
|
3
|
+
import ChevronDown from "@lucide/svelte/icons/chevron-down";
|
|
4
|
+
import { cn } from "$lib/utils.js";
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
ref = $bindable(null),
|
|
8
|
+
class: className,
|
|
9
|
+
children,
|
|
10
|
+
...restProps
|
|
11
|
+
}: WithoutChild<SelectPrimitive.TriggerProps> = $props();
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<SelectPrimitive.Trigger
|
|
15
|
+
bind:ref
|
|
16
|
+
class={cn(
|
|
17
|
+
"border-input ring-offset-background data-[placeholder]:text-muted-foreground focus:ring-ring flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border bg-transparent px-3 py-2 text-sm shadow-sm focus:outline-none focus:ring-1 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
|
|
18
|
+
className
|
|
19
|
+
)}
|
|
20
|
+
{...restProps}
|
|
21
|
+
>
|
|
22
|
+
{@render children?.()}
|
|
23
|
+
<ChevronDown class="size-4 opacity-50" />
|
|
24
|
+
</SelectPrimitive.Trigger>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Separator as SeparatorPrimitive } from "bits-ui";
|
|
3
|
+
import { cn } from "$lib/utils.js";
|
|
4
|
+
|
|
5
|
+
let {
|
|
6
|
+
ref = $bindable(null),
|
|
7
|
+
class: className,
|
|
8
|
+
orientation = "horizontal",
|
|
9
|
+
...restProps
|
|
10
|
+
}: SeparatorPrimitive.RootProps = $props();
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<SeparatorPrimitive.Root
|
|
14
|
+
bind:ref
|
|
15
|
+
class={cn(
|
|
16
|
+
"bg-border shrink-0",
|
|
17
|
+
orientation === "horizontal" ? "h-px w-full" : "min-h-full w-px",
|
|
18
|
+
className
|
|
19
|
+
)}
|
|
20
|
+
{orientation}
|
|
21
|
+
{...restProps}
|
|
22
|
+
/>
|
|
@@ -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 "$lib/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 "$lib/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 "$lib/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 shadow-sm 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 "$lib/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,187 @@
|
|
|
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 { lobb } from "$lib";
|
|
15
|
+
import MonacoEditor from "$lib/components/monacoEditor.svelte";
|
|
16
|
+
import Button from "$lib/components/ui/button/button.svelte";
|
|
17
|
+
import Input from "$lib/components/ui/input/input.svelte";
|
|
18
|
+
import { ctx } from "$lib/store.svelte";
|
|
19
|
+
import { location } from "@wjfe/n-savant";
|
|
20
|
+
import { Edit, Plus } from "lucide-svelte";
|
|
21
|
+
import { toast } from "svelte-sonner";
|
|
22
|
+
import { isEqual } from "lodash";
|
|
23
|
+
|
|
24
|
+
interface Props {
|
|
25
|
+
workflow: WorkflowEntry;
|
|
26
|
+
refreshSidebar: () => Promise<void>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
let { workflow = $bindable(), refreshSidebar }: Props = $props();
|
|
30
|
+
|
|
31
|
+
let initialWorkflow = $state.snapshot(workflow);
|
|
32
|
+
let workflowHasChanged = $state(false);
|
|
33
|
+
|
|
34
|
+
// track editor change
|
|
35
|
+
$effect(() => {
|
|
36
|
+
const hasChanged = !isEqual(workflow, initialWorkflow);
|
|
37
|
+
workflowHasChanged = hasChanged;
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
$effect(() => {
|
|
41
|
+
handleWorkflowEventChange(workflow.event_name);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
function handleCtrlSave() {
|
|
45
|
+
if (workflow.id) {
|
|
46
|
+
handleUpdateWorkflow();
|
|
47
|
+
} else {
|
|
48
|
+
handleCreateWorkflow();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
let types = $state("");
|
|
53
|
+
let eventsOptions = $derived([
|
|
54
|
+
{
|
|
55
|
+
label: "No Event",
|
|
56
|
+
value: "",
|
|
57
|
+
},
|
|
58
|
+
...ctx.meta.events.map((event) => ({
|
|
59
|
+
label: event.name,
|
|
60
|
+
value: event.name,
|
|
61
|
+
})),
|
|
62
|
+
]);
|
|
63
|
+
|
|
64
|
+
function handleWorkflowEventChange(eventName: WorkflowEntry["event_name"]) {
|
|
65
|
+
setTimeout(() => {
|
|
66
|
+
const event = ctx.meta.events.find(
|
|
67
|
+
(event) => event.name === eventName,
|
|
68
|
+
);
|
|
69
|
+
let localType = "";
|
|
70
|
+
if (event && event.inputSchema) {
|
|
71
|
+
localType += event.inputSchema;
|
|
72
|
+
} else {
|
|
73
|
+
localType += "type Input = unknown;";
|
|
74
|
+
}
|
|
75
|
+
if (ctx.meta.event_context_type) {
|
|
76
|
+
localType += ctx.meta.event_context_type;
|
|
77
|
+
} else {
|
|
78
|
+
localType += "type Context = unknown;";
|
|
79
|
+
}
|
|
80
|
+
if (event && event.outputSchema) {
|
|
81
|
+
localType += event.outputSchema;
|
|
82
|
+
} else {
|
|
83
|
+
localType += "type Output = Promise<unknown>;";
|
|
84
|
+
}
|
|
85
|
+
types = localType;
|
|
86
|
+
}, 100);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
async function handleCreateWorkflow() {
|
|
90
|
+
if (!workflow.name) {
|
|
91
|
+
toast.error("You need to specify a workflow name");
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const reponse = await lobb.createOne("core_workflows", workflow);
|
|
96
|
+
const result = await reponse.json();
|
|
97
|
+
const workflowEntry = result.data;
|
|
98
|
+
location.navigate(`/workflows/${workflowEntry.name}`);
|
|
99
|
+
await refreshSidebar();
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async function handleUpdateWorkflow() {
|
|
103
|
+
if (!workflow.id) {
|
|
104
|
+
throw new Error(
|
|
105
|
+
"For some reasont the id of the currentWorkflow doesnt exist",
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
const reponse = await lobb.updateOne("core_workflows", workflow.id, {
|
|
109
|
+
name: workflow.name,
|
|
110
|
+
event_name: workflow.event_name,
|
|
111
|
+
handler: workflow.handler,
|
|
112
|
+
});
|
|
113
|
+
const result = await reponse.json();
|
|
114
|
+
|
|
115
|
+
if (!(reponse.status >= 400)) {
|
|
116
|
+
toast.success("The workflow was updated successfully");
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
workflow = result.data;
|
|
120
|
+
|
|
121
|
+
await refreshSidebar();
|
|
122
|
+
}
|
|
123
|
+
</script>
|
|
124
|
+
|
|
125
|
+
<div class="flex flex-col h-full">
|
|
126
|
+
<div
|
|
127
|
+
class="flex justify-between items-start py-2 pl-9 pr-2 bg-background border-b"
|
|
128
|
+
>
|
|
129
|
+
<div class="flex gap-2 flex-wrap">
|
|
130
|
+
<Input
|
|
131
|
+
bind:value={workflow.name}
|
|
132
|
+
class="h-7 w-48 bg-background"
|
|
133
|
+
placeholder="Workflow name"
|
|
134
|
+
/>
|
|
135
|
+
<Input
|
|
136
|
+
bind:value={workflow.event_name}
|
|
137
|
+
class="h-7 w-48 bg-background"
|
|
138
|
+
placeholder="Workflow event"
|
|
139
|
+
list="events_options"
|
|
140
|
+
/>
|
|
141
|
+
<datalist id="events_options">
|
|
142
|
+
{#each eventsOptions as eventOption}
|
|
143
|
+
<option value={eventOption.value}>
|
|
144
|
+
{eventOption.label}
|
|
145
|
+
</option>
|
|
146
|
+
{/each}
|
|
147
|
+
</datalist>
|
|
148
|
+
<Input
|
|
149
|
+
bind:value={workflow.directory}
|
|
150
|
+
class="h-7 w-48 bg-background"
|
|
151
|
+
placeholder="Workflow directory"
|
|
152
|
+
/>
|
|
153
|
+
</div>
|
|
154
|
+
<div>
|
|
155
|
+
{#if workflow.id}
|
|
156
|
+
<Button
|
|
157
|
+
class="h-7 px-3 text-xs font-normal w-full"
|
|
158
|
+
variant="default"
|
|
159
|
+
onclick={handleUpdateWorkflow}
|
|
160
|
+
Icon={Edit}
|
|
161
|
+
disabled={!workflowHasChanged}
|
|
162
|
+
>
|
|
163
|
+
Save
|
|
164
|
+
</Button>
|
|
165
|
+
{:else}
|
|
166
|
+
<Button
|
|
167
|
+
class="h-7 px-3 text-xs font-normal w-full"
|
|
168
|
+
variant="default"
|
|
169
|
+
onclick={handleCreateWorkflow}
|
|
170
|
+
Icon={Plus}
|
|
171
|
+
>
|
|
172
|
+
Create
|
|
173
|
+
</Button>
|
|
174
|
+
{/if}
|
|
175
|
+
</div>
|
|
176
|
+
</div>
|
|
177
|
+
{#key types}
|
|
178
|
+
<MonacoEditor
|
|
179
|
+
type="typescript"
|
|
180
|
+
name="workflow"
|
|
181
|
+
class="h-full rounded-none border-none"
|
|
182
|
+
{types}
|
|
183
|
+
{handleCtrlSave}
|
|
184
|
+
bind:value={workflow.handler}
|
|
185
|
+
/>
|
|
186
|
+
{/key}
|
|
187
|
+
</div>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { toast } from "svelte-sonner";
|
|
2
|
+
import { ctx } from "./store.svelte";
|
|
3
|
+
import { openCreateDetailView, openUpdateDetailView } from "./components/detailView/store.svelte";
|
|
4
|
+
|
|
5
|
+
export async function emitEvent(eventName: string, input: Record<string, any>) {
|
|
6
|
+
const workflows = ctx.meta.studio_workflows.filter(
|
|
7
|
+
(workflow) => {
|
|
8
|
+
return eventName.startsWith(workflow.eventName);
|
|
9
|
+
},
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
for (let index = 0; index < workflows.length; index++) {
|
|
13
|
+
const workflow = workflows[index];
|
|
14
|
+
try {
|
|
15
|
+
const localOutput = await workflow.handler(
|
|
16
|
+
input,
|
|
17
|
+
await getEventContext(),
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
if (localOutput) {
|
|
21
|
+
input = localOutput;
|
|
22
|
+
}
|
|
23
|
+
} catch (error) {
|
|
24
|
+
toast.error((error as any).message);
|
|
25
|
+
throw error;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return input;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function getEventContext() {
|
|
33
|
+
return {
|
|
34
|
+
toast,
|
|
35
|
+
openCreateDetailView,
|
|
36
|
+
openUpdateDetailView,
|
|
37
|
+
};
|
|
38
|
+
}
|
package/src/lib/index.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Lobb } from "./Lobb";
|
|
2
|
+
import { ctx } from "$lib/store.svelte";
|
|
3
|
+
import { toast } from "svelte-sonner";
|
|
4
|
+
|
|
5
|
+
export const lobb = new Lobb(ctx.lobbUrl);
|
|
6
|
+
|
|
7
|
+
// logging the message if got any bad responses
|
|
8
|
+
lobb.onResponse(async (response) => {
|
|
9
|
+
if (response.status >= 400) {
|
|
10
|
+
const body = await response.json();
|
|
11
|
+
toast.error(body.message);
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export function createSet(lastNumber: number): Set<number> {
|
|
16
|
+
const set = new Set() as Set<number>;
|
|
17
|
+
for (let i = 0; i <= lastNumber; i++) {
|
|
18
|
+
set.add(i);
|
|
19
|
+
}
|
|
20
|
+
return set;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function moveElement<T>(array: T[], fromIndex: number, toIndex: number) {
|
|
24
|
+
if (
|
|
25
|
+
fromIndex < 0 || fromIndex >= array.length || toIndex < 0 ||
|
|
26
|
+
toIndex >= array.length
|
|
27
|
+
) {
|
|
28
|
+
throw new Error("Index out of bounds");
|
|
29
|
+
}
|
|
30
|
+
const [element] = array.splice(fromIndex, 1);
|
|
31
|
+
array.splice(toIndex, 0, element);
|
|
32
|
+
return array;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function pxToRem(px: number) {
|
|
36
|
+
const rootFontSize = parseFloat(
|
|
37
|
+
getComputedStyle(document.documentElement).fontSize,
|
|
38
|
+
);
|
|
39
|
+
return px / rootFontSize;
|
|
40
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { CTX } from './store.types';
|
|
2
|
+
import pkg from '../../package.json';
|
|
3
|
+
|
|
4
|
+
if (!window.APP_ENV) {
|
|
5
|
+
window.APP_ENV = {};
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
if (window.APP_ENV.LOBB_URL === '%LOBB_URL%') {
|
|
9
|
+
window.APP_ENV.LOBB_URL = null;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const ctx: CTX = $state.raw({
|
|
13
|
+
studioVersion: pkg.version,
|
|
14
|
+
lobbUrl: window.APP_ENV.LOBB_URL || localStorage.getItem("lobb_url"),
|
|
15
|
+
extensions: {},
|
|
16
|
+
meta: {
|
|
17
|
+
collections: null,
|
|
18
|
+
extensions: null,
|
|
19
|
+
filter: null
|
|
20
|
+
},
|
|
21
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Extension } from "../extensions/extension.types";
|
|
2
|
+
|
|
3
|
+
interface Collection {
|
|
4
|
+
category: string;
|
|
5
|
+
owner: string;
|
|
6
|
+
fields: Record<string, any>;
|
|
7
|
+
singleton: boolean;
|
|
8
|
+
}
|
|
9
|
+
type Collections = Record<string, Collection>;
|
|
10
|
+
|
|
11
|
+
interface Meta {
|
|
12
|
+
version: string;
|
|
13
|
+
relations: Array<any>;
|
|
14
|
+
collections: Collections;
|
|
15
|
+
extensions: Record<string, any>;
|
|
16
|
+
filter: any;
|
|
17
|
+
events: any[];
|
|
18
|
+
event_context_type: string;
|
|
19
|
+
studio_workflows: any[];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface CTX {
|
|
23
|
+
studioVersion: string;
|
|
24
|
+
lobbUrl: string | null;
|
|
25
|
+
extensions: Record<string, Extension>;
|
|
26
|
+
meta: Meta;
|
|
27
|
+
currentUrl: URL;
|
|
28
|
+
}
|