@lobb-js/studio 0.30.0 → 0.32.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/actions.d.ts +2 -0
- package/dist/components/Studio.svelte +1 -10
- package/dist/components/dataTable/dataTable.svelte +104 -39
- package/dist/components/dataTable/dataTable.svelte.d.ts +4 -1
- package/dist/components/dataTable/fieldCell.svelte +7 -4
- package/dist/components/dataTable/fieldCell.svelte.d.ts +2 -2
- package/dist/components/dataTable/filter.svelte +0 -15
- package/dist/components/dataTable/header.svelte +13 -14
- package/dist/components/dataTable/header.svelte.d.ts +3 -2
- package/dist/components/dataTable/numberCell.svelte +28 -0
- package/dist/components/dataTable/numberCell.svelte.d.ts +7 -0
- package/dist/components/dataTable/polymorphicFieldCell.svelte +3 -3
- package/dist/components/dataTable/polymorphicFieldCell.svelte.d.ts +2 -2
- package/dist/components/dataTablePopup/dataTablePopup.svelte +17 -0
- package/dist/components/dataTablePopup/dataTablePopup.svelte.d.ts +2 -0
- package/dist/components/detailView/create/createDetailView.svelte +28 -54
- package/dist/components/detailView/create/createDetailView.svelte.d.ts +4 -3
- package/dist/components/detailView/create/createDetailViewChildren.svelte +113 -0
- package/dist/components/detailView/create/createDetailViewChildren.svelte.d.ts +9 -0
- package/dist/components/detailView/create/createManyView.svelte +2 -2
- package/dist/components/detailView/detailView.svelte +6 -1
- package/dist/components/detailView/fieldInput.svelte +7 -5
- package/dist/components/detailView/update/updateDetailView.svelte +46 -40
- package/dist/components/detailView/update/updateDetailView.svelte.d.ts +5 -3
- package/dist/components/detailView/update/updateDetailViewButton.svelte +0 -1
- package/dist/components/detailView/update/updateDetailViewChildren.svelte +122 -0
- package/dist/components/detailView/update/updateDetailViewChildren.svelte.d.ts +10 -0
- package/dist/components/detailView/utils.d.ts +1 -2
- package/dist/components/importButton.svelte +1 -1
- package/dist/components/miniSidebar.svelte +6 -3
- package/dist/components/richTextEditor.svelte +2 -0
- package/dist/components/routes/extensions/extension.svelte +1 -1
- package/dist/components/routes/home.svelte +35 -21
- package/dist/components/ui/input/numberInput.svelte +104 -0
- package/dist/components/ui/input/numberInput.svelte.d.ts +9 -0
- package/dist/components/workflowEditor.svelte +6 -4
- package/package.json +4 -3
- package/src/lib/actions.ts +2 -0
- package/src/lib/components/Studio.svelte +1 -10
- package/src/lib/components/dataTable/dataTable.svelte +104 -39
- package/src/lib/components/dataTable/fieldCell.svelte +7 -4
- package/src/lib/components/dataTable/filter.svelte +0 -15
- package/src/lib/components/dataTable/header.svelte +13 -14
- package/src/lib/components/dataTable/numberCell.svelte +28 -0
- package/src/lib/components/dataTable/polymorphicFieldCell.svelte +3 -3
- package/src/lib/components/dataTablePopup/dataTablePopup.svelte +17 -0
- package/src/lib/components/detailView/create/createDetailView.svelte +28 -54
- package/src/lib/components/detailView/create/createDetailViewChildren.svelte +113 -0
- package/src/lib/components/detailView/create/createManyView.svelte +2 -2
- package/src/lib/components/detailView/detailView.svelte +6 -1
- package/src/lib/components/detailView/fieldInput.svelte +7 -5
- package/src/lib/components/detailView/update/updateDetailView.svelte +46 -40
- package/src/lib/components/detailView/update/updateDetailViewButton.svelte +0 -1
- package/src/lib/components/detailView/update/updateDetailViewChildren.svelte +122 -0
- package/src/lib/components/detailView/utils.ts +1 -1
- package/src/lib/components/importButton.svelte +1 -1
- package/src/lib/components/miniSidebar.svelte +6 -3
- package/src/lib/components/richTextEditor.svelte +2 -0
- package/src/lib/components/routes/extensions/extension.svelte +1 -1
- package/src/lib/components/routes/home.svelte +35 -21
- package/src/lib/components/ui/input/numberInput.svelte +104 -0
- package/src/lib/components/workflowEditor.svelte +6 -4
- package/dist/components/breadCrumbs.svelte +0 -61
- package/dist/components/breadCrumbs.svelte.d.ts +0 -3
- package/dist/components/detailView/update/detailViewChildren.svelte +0 -61
- package/dist/components/detailView/update/detailViewChildren.svelte.d.ts +0 -9
- package/dist/components/header.svelte +0 -45
- package/dist/components/header.svelte.d.ts +0 -6
- package/src/lib/components/breadCrumbs.svelte +0 -61
- package/src/lib/components/detailView/update/detailViewChildren.svelte +0 -61
- package/src/lib/components/header.svelte +0 -45
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import DataTable from "../../dataTable/dataTable.svelte";
|
|
3
|
+
import { getStudioContext } from "../../../context";
|
|
4
|
+
import { Table, Link, Plus } from "lucide-svelte";
|
|
5
|
+
import { untrack } from "svelte";
|
|
6
|
+
import CreateDetailViewButton from "../create/createDetailViewButton.svelte";
|
|
7
|
+
import SelectRecord from "../../selectRecord.svelte";
|
|
8
|
+
|
|
9
|
+
const { ctx } = getStudioContext();
|
|
10
|
+
|
|
11
|
+
import type { Changes, ChildrenChanges } from "../utils";
|
|
12
|
+
|
|
13
|
+
interface LocalProp {
|
|
14
|
+
collectionName: string;
|
|
15
|
+
entry: any;
|
|
16
|
+
changes?: Changes;
|
|
17
|
+
onChanges?: (children: Changes["children"]) => void;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
let { collectionName, entry, changes, onChanges }: LocalProp = $props();
|
|
21
|
+
|
|
22
|
+
const children = (ctx.meta.collections[collectionName]?.children ?? [])
|
|
23
|
+
.filter((c: any) => c.type === "fk" || c.type === "m2m" || c.type === "polymorphic");
|
|
24
|
+
|
|
25
|
+
let localChildren = $state<Changes["children"]>(untrack(() => changes?.children ?? {}));
|
|
26
|
+
let serverCounts = $state<Record<string, number | undefined>>({});
|
|
27
|
+
|
|
28
|
+
function handleChildChanges(collection: string, updated: ChildrenChanges) {
|
|
29
|
+
localChildren[collection] = updated;
|
|
30
|
+
onChanges?.($state.snapshot(localChildren));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function handleDataLoad(collection: string, total: number) {
|
|
34
|
+
serverCounts[collection] = total;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function handleEmptyCreate(collection: string, c: Changes) {
|
|
38
|
+
if (!localChildren[collection]) {
|
|
39
|
+
localChildren[collection] = { created: [], updated: [], deleted: [], linked: [], unlinked: [] };
|
|
40
|
+
}
|
|
41
|
+
localChildren[collection].created.push({ data: c.data });
|
|
42
|
+
onChanges?.($state.snapshot(localChildren));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function handleEmptyLink(collection: string, record: any) {
|
|
46
|
+
if (!localChildren[collection]) {
|
|
47
|
+
localChildren[collection] = { created: [], updated: [], deleted: [], linked: [], unlinked: [] };
|
|
48
|
+
}
|
|
49
|
+
localChildren[collection].linked.push(record);
|
|
50
|
+
onChanges?.($state.snapshot(localChildren));
|
|
51
|
+
}
|
|
52
|
+
</script>
|
|
53
|
+
|
|
54
|
+
{#if children.length}
|
|
55
|
+
<div class="flex flex-col gap-3 border-t p-4">
|
|
56
|
+
<div class="flex items-center gap-2">
|
|
57
|
+
<Link size="14" class="text-muted-foreground" />
|
|
58
|
+
<span class="text-sm font-medium">Sub Records</span>
|
|
59
|
+
</div>
|
|
60
|
+
{#each children as child}
|
|
61
|
+
{@const serverCount = serverCounts[child.collection]}
|
|
62
|
+
{@const localAdditions = (localChildren[child.collection]?.created.length ?? 0) + (localChildren[child.collection]?.linked.length ?? 0)}
|
|
63
|
+
{@const showEmpty = serverCount !== undefined && serverCount === 0 && localAdditions === 0}
|
|
64
|
+
{#if showEmpty}
|
|
65
|
+
<div class="rounded-lg border bg-muted-soft overflow-hidden flex flex-col">
|
|
66
|
+
<div class="flex flex-col items-center justify-center gap-3 py-6 px-4">
|
|
67
|
+
<div class="flex flex-col items-center gap-2 text-center">
|
|
68
|
+
<div class="flex items-center gap-1.5 text-sm font-medium text-muted-foreground">
|
|
69
|
+
<span>No records in</span>
|
|
70
|
+
<span class="rounded-md border bg-muted px-2 py-0.5 text-xs font-normal">{child.collection}</span>
|
|
71
|
+
</div>
|
|
72
|
+
<span class="text-xs text-muted-foreground/70">Create a new record or link an existing one.</span>
|
|
73
|
+
</div>
|
|
74
|
+
<div class="flex gap-2">
|
|
75
|
+
<SelectRecord
|
|
76
|
+
collectionName={child.collection}
|
|
77
|
+
variant="outline"
|
|
78
|
+
class="h-7 px-3 text-xs font-normal"
|
|
79
|
+
Icon={Link}
|
|
80
|
+
onSelect={(r) => handleEmptyLink(child.collection, r)}
|
|
81
|
+
>
|
|
82
|
+
Link
|
|
83
|
+
</SelectRecord>
|
|
84
|
+
<CreateDetailViewButton
|
|
85
|
+
collectionName={child.collection}
|
|
86
|
+
variant="default"
|
|
87
|
+
class="h-7 px-3 text-xs font-normal"
|
|
88
|
+
Icon={Plus}
|
|
89
|
+
onChanges={(c) => handleEmptyCreate(child.collection, c)}
|
|
90
|
+
>
|
|
91
|
+
Create
|
|
92
|
+
</CreateDetailViewButton>
|
|
93
|
+
</div>
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
{:else}
|
|
97
|
+
<div class="rounded-lg border bg-background overflow-hidden flex flex-col max-h-96">
|
|
98
|
+
<DataTable
|
|
99
|
+
collectionName={child.collection}
|
|
100
|
+
searchParams={{ children_of: collectionName, parent_id: entry.id }}
|
|
101
|
+
parentContext={{ collectionName, recordId: entry.id }}
|
|
102
|
+
onChanges={(updated) => handleChildChanges(child.collection, updated)}
|
|
103
|
+
changes={localChildren[child.collection]}
|
|
104
|
+
showImport={false}
|
|
105
|
+
showHeader={true}
|
|
106
|
+
showFooter={true}
|
|
107
|
+
showDelete={child.type === "fk" || child.type === "m2m"}
|
|
108
|
+
tableProps={{ showLastColumnBorder: false, showLastRowBorder: true }}
|
|
109
|
+
onDataLoad={(total) => handleDataLoad(child.collection, total)}
|
|
110
|
+
>
|
|
111
|
+
{#snippet headerLeft()}
|
|
112
|
+
<div class="flex items-center gap-2 px-1">
|
|
113
|
+
<Table size="14" class="text-muted-foreground" />
|
|
114
|
+
<span class="text-sm font-medium">{child.collection}</span>
|
|
115
|
+
</div>
|
|
116
|
+
{/snippet}
|
|
117
|
+
</DataTable>
|
|
118
|
+
</div>
|
|
119
|
+
{/if}
|
|
120
|
+
{/each}
|
|
121
|
+
</div>
|
|
122
|
+
{/if}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Changes } from "../utils";
|
|
2
|
+
interface LocalProp {
|
|
3
|
+
collectionName: string;
|
|
4
|
+
entry: any;
|
|
5
|
+
changes?: Changes;
|
|
6
|
+
onChanges?: (children: Changes["children"]) => void;
|
|
7
|
+
}
|
|
8
|
+
declare const UpdateDetailViewChildren: import("svelte").Component<LocalProp, {}, "">;
|
|
9
|
+
type UpdateDetailViewChildren = ReturnType<typeof UpdateDetailViewChildren>;
|
|
10
|
+
export default UpdateDetailViewChildren;
|
|
@@ -132,7 +132,7 @@
|
|
|
132
132
|
importResults = [];
|
|
133
133
|
let hasSuccess = false;
|
|
134
134
|
for (const row of finalRows) {
|
|
135
|
-
const response = await lobb.createOne(collectionName, row);
|
|
135
|
+
const response = await lobb.createOne(collectionName, { data: row });
|
|
136
136
|
if (response.ok) {
|
|
137
137
|
importResults.push({ row, error: null });
|
|
138
138
|
hasSuccess = true;
|
|
@@ -90,12 +90,15 @@
|
|
|
90
90
|
// prefix of everything); other items use startsWith so sub-paths
|
|
91
91
|
// (e.g. /studio/collections/risks) still highlight their parent.
|
|
92
92
|
// Popover items with children are active when any of their children match.
|
|
93
|
-
|
|
93
|
+
// SvelteKit's pathname can come back with a trailing slash (`/studio/`)
|
|
94
|
+
// depending on config, so we normalize it before comparing.
|
|
95
|
+
const currentPath = $derived(page.url.pathname.replace(/\/$/, "") || "/");
|
|
94
96
|
function isItemActive(item: any): boolean {
|
|
95
97
|
if (item.navs) return item.navs.some((c: any) => isItemActive(c));
|
|
96
98
|
if (!item.href) return false;
|
|
97
|
-
|
|
98
|
-
|
|
99
|
+
const itemHref = item.href.replace(/\/$/, "") || "/";
|
|
100
|
+
if (itemHref === "/studio") return currentPath === "/studio";
|
|
101
|
+
return currentPath === itemHref || currentPath.startsWith(itemHref + "/");
|
|
99
102
|
}
|
|
100
103
|
|
|
101
104
|
// onMount is enough — Studio gets remounted on login/logout (see
|
|
@@ -3,29 +3,43 @@
|
|
|
3
3
|
import { goto } from "$app/navigation";
|
|
4
4
|
import { ArrowRight } from "lucide-svelte";
|
|
5
5
|
import HomeFooter from "./homeFooter.svelte";
|
|
6
|
+
import ExtensionsComponents from "../extensionsComponents.svelte";
|
|
7
|
+
import { getExtensionUtils } from "../../extensions/extensionUtils";
|
|
8
|
+
import { getStudioContext } from "../../context";
|
|
9
|
+
|
|
10
|
+
const { lobb, ctx } = getStudioContext();
|
|
6
11
|
</script>
|
|
7
12
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
<!--
|
|
14
|
+
Any extension that registers a `pages.home` component takes over /studio
|
|
15
|
+
(e.g. an app-specific overview dashboard). ExtensionsComponents falls
|
|
16
|
+
back to rendering its children when nothing matches, so the default
|
|
17
|
+
Lobb welcome below stays as the safety net for projects without an
|
|
18
|
+
overriding extension.
|
|
19
|
+
-->
|
|
20
|
+
<ExtensionsComponents name="pages.home" utils={getExtensionUtils(lobb, ctx)}>
|
|
21
|
+
<div class="flex h-full flex-col">
|
|
22
|
+
<div
|
|
23
|
+
class="flex flex-1 w-full flex-col items-center justify-center gap-4 text-muted-foreground"
|
|
24
|
+
>
|
|
25
|
+
<div class="flex flex-col items-center justify-center p-4">
|
|
26
|
+
<div class="text-3xl">Welcome to Lobb!</div>
|
|
27
|
+
<div class="text-xs text-center">
|
|
28
|
+
Your journey starts here. Explore and make the most of your
|
|
29
|
+
experience.
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
<div class="flex flex-col items-center justify-center">
|
|
33
|
+
<Button
|
|
34
|
+
Icon={ArrowRight}
|
|
35
|
+
variant="outline"
|
|
36
|
+
class="h-7 px-3 text-xs font-normal"
|
|
37
|
+
onclick={() => goto("/studio/collections")}
|
|
38
|
+
>
|
|
39
|
+
Go to collections
|
|
40
|
+
</Button>
|
|
17
41
|
</div>
|
|
18
42
|
</div>
|
|
19
|
-
<
|
|
20
|
-
<Button
|
|
21
|
-
Icon={ArrowRight}
|
|
22
|
-
variant="outline"
|
|
23
|
-
class="h-7 px-3 text-xs font-normal"
|
|
24
|
-
onclick={() => goto("/studio/collections")}
|
|
25
|
-
>
|
|
26
|
-
Go to collections
|
|
27
|
-
</Button>
|
|
28
|
-
</div>
|
|
43
|
+
<HomeFooter />
|
|
29
44
|
</div>
|
|
30
|
-
|
|
31
|
-
</div>
|
|
45
|
+
</ExtensionsComponents>
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import IMask from "imask";
|
|
3
|
+
import type { HTMLInputAttributes } from "svelte/elements";
|
|
4
|
+
import { cn } from "../../../utils.js";
|
|
5
|
+
|
|
6
|
+
// Locale-neutral grouping: space for thousands, dot for decimals
|
|
7
|
+
// (ISO 31-0). Norwegian, French, scientific contexts — same shape, and
|
|
8
|
+
// space can't be confused with comma-as-decimal vs comma-as-thousands.
|
|
9
|
+
const THOUSANDS = " ";
|
|
10
|
+
const RADIX = ".";
|
|
11
|
+
|
|
12
|
+
type Props = Omit<HTMLInputAttributes, "type" | "value" | "step"> & {
|
|
13
|
+
value?: number | string | null;
|
|
14
|
+
// 0 = integer-only, > 0 = allow that many decimal places.
|
|
15
|
+
scale?: number;
|
|
16
|
+
// When false, render a plain browser number input — no masking, no
|
|
17
|
+
// formatting. Default false so the component is safe to drop in
|
|
18
|
+
// anywhere; opt into grouping only where it makes sense.
|
|
19
|
+
groupDigits?: boolean;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
let {
|
|
23
|
+
value = $bindable<number | string | null | undefined>(),
|
|
24
|
+
scale = 0,
|
|
25
|
+
groupDigits = false,
|
|
26
|
+
class: className,
|
|
27
|
+
...rest
|
|
28
|
+
}: Props = $props();
|
|
29
|
+
|
|
30
|
+
let inputEl: HTMLInputElement | undefined = $state();
|
|
31
|
+
let mask: ReturnType<typeof IMask> | null = null;
|
|
32
|
+
// Re-entrance guard: imask's `accept` event fires when we programmatically
|
|
33
|
+
// set unmaskedValue, which would create a sync→reflect loop with the
|
|
34
|
+
// "external value changed" effect below.
|
|
35
|
+
let applyingExternal = false;
|
|
36
|
+
|
|
37
|
+
$effect(() => {
|
|
38
|
+
if (!groupDigits) return;
|
|
39
|
+
if (!inputEl) return;
|
|
40
|
+
mask = IMask(inputEl, {
|
|
41
|
+
mask: Number,
|
|
42
|
+
thousandsSeparator: THOUSANDS,
|
|
43
|
+
radix: RADIX,
|
|
44
|
+
scale,
|
|
45
|
+
signed: true,
|
|
46
|
+
padFractionalZeros: false,
|
|
47
|
+
normalizeZeros: true,
|
|
48
|
+
// Allow the user to type either radix; imask remaps to the chosen
|
|
49
|
+
// one and ignores stray locale separators on input.
|
|
50
|
+
mapToRadix: [",", "."],
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
mask.on("accept", () => {
|
|
54
|
+
if (applyingExternal) return;
|
|
55
|
+
const unmasked = mask!.unmaskedValue;
|
|
56
|
+
value = unmasked === "" ? null : Number(unmasked);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
applyingExternal = true;
|
|
60
|
+
mask.unmaskedValue = value == null ? "" : String(value);
|
|
61
|
+
applyingExternal = false;
|
|
62
|
+
|
|
63
|
+
return () => {
|
|
64
|
+
mask?.destroy();
|
|
65
|
+
mask = null;
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// Sync external value changes back into the mask (e.g. form reset, parent
|
|
70
|
+
// clearing the value). No-op when grouping is off.
|
|
71
|
+
$effect(() => {
|
|
72
|
+
const v = value;
|
|
73
|
+
if (!mask) return;
|
|
74
|
+
const next = v == null ? "" : String(v);
|
|
75
|
+
if (mask.unmaskedValue === next) return;
|
|
76
|
+
applyingExternal = true;
|
|
77
|
+
mask.unmaskedValue = next;
|
|
78
|
+
applyingExternal = false;
|
|
79
|
+
});
|
|
80
|
+
</script>
|
|
81
|
+
|
|
82
|
+
{#if groupDigits}
|
|
83
|
+
<input
|
|
84
|
+
bind:this={inputEl}
|
|
85
|
+
type="text"
|
|
86
|
+
inputmode={scale > 0 ? "decimal" : "numeric"}
|
|
87
|
+
class={cn(
|
|
88
|
+
"border-input placeholder:text-muted-foreground focus-visible:ring-ring flex h-9 w-full rounded-md border bg-transparent px-3 py-1 text-base transition-colors focus-visible:outline-none focus-visible:ring-1 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
89
|
+
className,
|
|
90
|
+
)}
|
|
91
|
+
{...rest}
|
|
92
|
+
/>
|
|
93
|
+
{:else}
|
|
94
|
+
<input
|
|
95
|
+
type="number"
|
|
96
|
+
step={scale > 0 ? "any" : "1"}
|
|
97
|
+
class={cn(
|
|
98
|
+
"border-input placeholder:text-muted-foreground focus-visible:ring-ring flex h-9 w-full rounded-md border bg-transparent px-3 py-1 text-base transition-colors focus-visible:outline-none focus-visible:ring-1 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
99
|
+
className,
|
|
100
|
+
)}
|
|
101
|
+
bind:value
|
|
102
|
+
{...rest}
|
|
103
|
+
/>
|
|
104
|
+
{/if}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { HTMLInputAttributes } from "svelte/elements";
|
|
2
|
+
type Props = Omit<HTMLInputAttributes, "type" | "value" | "step"> & {
|
|
3
|
+
value?: number | string | null;
|
|
4
|
+
scale?: number;
|
|
5
|
+
groupDigits?: boolean;
|
|
6
|
+
};
|
|
7
|
+
declare const NumberInput: import("svelte").Component<Props, {}, "value">;
|
|
8
|
+
type NumberInput = ReturnType<typeof NumberInput>;
|
|
9
|
+
export default NumberInput;
|
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
return;
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
const reponse = await lobb.createOne("core_workflows", workflow);
|
|
96
|
+
const reponse = await lobb.createOne("core_workflows", { data: workflow });
|
|
97
97
|
const result = await reponse.json();
|
|
98
98
|
const workflowEntry = result.data;
|
|
99
99
|
goto(`/studio/workflows/${workflowEntry.name}`);
|
|
@@ -107,9 +107,11 @@
|
|
|
107
107
|
);
|
|
108
108
|
}
|
|
109
109
|
const reponse = await lobb.updateOne("core_workflows", workflow.id, {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
110
|
+
data: {
|
|
111
|
+
name: workflow.name,
|
|
112
|
+
event_name: workflow.event_name,
|
|
113
|
+
handler: workflow.handler,
|
|
114
|
+
},
|
|
113
115
|
});
|
|
114
116
|
const result = await reponse.json();
|
|
115
117
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobb-js/studio",
|
|
3
3
|
"license": "UNLICENSED",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.32.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"postpublish": "./scripts/postpublish.sh"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@lobb-js/core": "^0.
|
|
45
|
+
"@lobb-js/core": "^0.33.0",
|
|
46
46
|
"@chromatic-com/storybook": "^4.1.2",
|
|
47
47
|
"@storybook/addon-a11y": "^10.0.1",
|
|
48
48
|
"@storybook/addon-docs": "^10.0.1",
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
"@codemirror/view": "^6.39.12",
|
|
88
88
|
"@dagrejs/dagre": "^1.1.5",
|
|
89
89
|
"@internationalized/date": "^3.12.0",
|
|
90
|
-
"@lobb-js/sdk": "^0.
|
|
90
|
+
"@lobb-js/sdk": "^0.3.0",
|
|
91
91
|
"@lucide/svelte": "^0.563.1",
|
|
92
92
|
"@tailwindcss/vite": "^4.3.0",
|
|
93
93
|
"@tiptap/core": "^3.0.0",
|
|
@@ -101,6 +101,7 @@
|
|
|
101
101
|
"codemirror": "^6.0.2",
|
|
102
102
|
"fflate": "^0.8.2",
|
|
103
103
|
"fuse.js": "^7.3.0",
|
|
104
|
+
"imask": "^7.6.1",
|
|
104
105
|
"javascript-time-ago": "^2.6.4",
|
|
105
106
|
"json-stable-stringify": "^1.3.0",
|
|
106
107
|
"lucide-svelte": "^0.488.0",
|
package/src/lib/actions.ts
CHANGED
|
@@ -24,6 +24,8 @@ export interface OpenDataTableDrawerProps {
|
|
|
24
24
|
export interface OpenDataTablePopupProps {
|
|
25
25
|
collectionName: string;
|
|
26
26
|
filter?: Record<string, any>;
|
|
27
|
+
sort?: Record<string, "asc" | "desc">;
|
|
28
|
+
limit?: number;
|
|
27
29
|
title?: string;
|
|
28
30
|
showHeader?: boolean;
|
|
29
31
|
showFooter?: boolean;
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
import { ModeWatcher } from "mode-watcher";
|
|
5
5
|
import { createLobb } from "../store.svelte";
|
|
6
6
|
import { setStudioContext } from "../context";
|
|
7
|
-
import Header from "./header.svelte";
|
|
8
7
|
import { LoaderCircle, ServerOff } from "lucide-svelte";
|
|
9
8
|
import MiniSidebar from "./miniSidebar.svelte";
|
|
10
9
|
import * as Tooltip from "./ui/tooltip";
|
|
@@ -107,8 +106,7 @@
|
|
|
107
106
|
style="display: grid; grid-template-columns: {isSmallScreen ? '1fr' : '3.5rem 1fr'};"
|
|
108
107
|
>
|
|
109
108
|
<MiniSidebar />
|
|
110
|
-
<div class="
|
|
111
|
-
<Header />
|
|
109
|
+
<div class="min-h-0 h-screen overflow-hidden">
|
|
112
110
|
{#if page.url.pathname.replace(/\/$/, "") === "/studio"}
|
|
113
111
|
<Home />
|
|
114
112
|
{:else if page.url.pathname.startsWith("/studio/collections")}
|
|
@@ -131,10 +129,3 @@
|
|
|
131
129
|
</main>
|
|
132
130
|
</Tooltip.Provider>
|
|
133
131
|
{/if}
|
|
134
|
-
|
|
135
|
-
<style>
|
|
136
|
-
.second_grid {
|
|
137
|
-
display: grid;
|
|
138
|
-
grid-template-rows: 2.5rem 1fr;
|
|
139
|
-
}
|
|
140
|
-
</style>
|