@lobb-js/studio 0.28.6 → 0.29.1
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/README.md +1 -0
- package/dist/actions.d.ts +2 -0
- package/dist/components/Studio.svelte +46 -47
- package/dist/components/StudioRoot.svelte +19 -0
- package/dist/components/StudioRoot.svelte.d.ts +6 -0
- package/dist/components/breadCrumbs.svelte +5 -4
- package/dist/components/codeEditor.svelte +1 -1
- package/dist/components/combobox.svelte +3 -3
- package/dist/components/confirmationDialog/confirmationDialog.svelte +1 -1
- package/dist/components/dataTable/dataTable.svelte +108 -101
- package/dist/components/dataTable/dataTable.svelte.d.ts +5 -20
- package/dist/components/dataTable/dataTableTabs.svelte +4 -2
- package/dist/components/dataTable/dataTableTabs.svelte.d.ts +2 -0
- package/dist/components/dataTable/filter.svelte +1 -1
- package/dist/components/dataTable/filterButton.svelte +1 -1
- package/dist/components/dataTable/header.svelte +30 -47
- package/dist/components/dataTable/header.svelte.d.ts +4 -2
- package/dist/components/dataTable/listViewChildren.svelte +4 -6
- package/dist/components/dataTable/listViewChildren.svelte.d.ts +0 -1
- package/dist/components/dataTable/sort.svelte +1 -1
- package/dist/components/dataTable/sortButton.svelte +2 -2
- package/dist/components/dataTable/table.svelte +8 -10
- package/dist/components/dataTable/table.svelte.d.ts +0 -1
- package/dist/components/dataTableDrawer/dataTableDrawer.svelte +4 -1
- package/dist/components/dataTableDrawer/dataTableDrawer.svelte.d.ts +2 -0
- package/dist/components/detailView/create/children.svelte +2 -2
- package/dist/components/detailView/create/createDetailView.svelte +81 -88
- package/dist/components/detailView/create/createDetailView.svelte.d.ts +2 -2
- package/dist/components/detailView/create/createDetailViewButton.svelte +2 -2
- package/dist/components/detailView/create/createDetailViewButton.svelte.d.ts +1 -1
- package/dist/components/detailView/create/createManyView.svelte +12 -10
- package/dist/components/detailView/detailView.svelte +81 -0
- package/dist/components/detailView/detailView.svelte.d.ts +8 -0
- package/dist/components/detailView/fieldInput.svelte +11 -11
- package/dist/components/detailView/fieldInputReplacement.svelte +8 -8
- package/dist/components/detailView/passwordInput.svelte +1 -1
- package/dist/components/detailView/update/detailViewChildren.svelte +15 -26
- package/dist/components/detailView/update/detailViewChildren.svelte.d.ts +3 -8
- package/dist/components/detailView/update/updateDetailView.svelte +90 -69
- package/dist/components/detailView/update/updateDetailView.svelte.d.ts +2 -2
- package/dist/components/detailView/update/updateDetailViewButton.svelte +3 -2
- package/dist/components/detailView/update/updateDetailViewButton.svelte.d.ts +1 -1
- package/dist/components/detailView/utils.d.ts +17 -0
- package/dist/components/diffViewer.svelte +1 -1
- package/dist/components/extensionsComponents.svelte +3 -1
- package/dist/components/foreingKeyInput.svelte +2 -2
- package/dist/components/importButton.svelte +12 -9
- package/dist/components/landing.svelte +7 -0
- package/dist/components/landing.svelte.d.ts +6 -14
- package/dist/components/miniSidebar.svelte +90 -19
- package/dist/components/miniSidebar.svelte.d.ts +2 -17
- package/dist/components/polymorphicInput.svelte +1 -1
- package/dist/components/rangeCalendarButton.svelte +13 -13
- package/dist/components/richTextEditor.svelte +1 -1
- package/dist/components/routes/collections/collection.svelte +3 -3
- package/dist/components/routes/collections/collections.svelte +34 -12
- package/dist/components/routes/data_model/dataModel.svelte +6 -28
- package/dist/components/routes/data_model/dataModel.svelte.d.ts +17 -2
- package/dist/components/routes/extensions/extension.svelte +1 -1
- package/dist/components/routes/extensions/publicExtension.svelte +19 -0
- package/dist/components/routes/extensions/publicExtension.svelte.d.ts +13 -0
- package/dist/components/routes/home.svelte +3 -3
- package/dist/components/routes/workflows/workflows.svelte +9 -9
- package/dist/components/selectRecord.svelte +2 -21
- package/dist/components/setServerPage.svelte +1 -1
- package/dist/components/sidebar/sidebar.svelte +1 -1
- package/dist/components/sidebar/sidebarElements.svelte +4 -4
- package/dist/components/singletone.svelte +4 -6
- package/dist/components/ui/alert-dialog/alert-dialog-action.svelte +1 -1
- package/dist/components/ui/alert-dialog/alert-dialog-cancel.svelte +1 -1
- package/dist/components/ui/button/button.svelte +2 -3
- package/dist/components/ui/command/command-dialog.svelte +1 -1
- package/dist/components/ui/range-calendar/range-calendar-day.svelte +1 -1
- package/dist/components/ui/range-calendar/range-calendar-next-button.svelte +1 -1
- package/dist/components/ui/range-calendar/range-calendar-prev-button.svelte +1 -1
- package/dist/components/ui/select/select-separator.svelte +1 -1
- package/dist/components/workflowEditor.svelte +5 -5
- package/dist/eventSystem.d.ts +1 -1
- package/dist/eventSystem.js +7 -5
- package/dist/extensions/extension.types.d.ts +38 -14
- package/dist/extensions/extensionUtils.js +4 -2
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/dist/store.types.d.ts +2 -2
- package/dist/studioLifecycle.svelte.d.ts +2 -0
- package/dist/studioLifecycle.svelte.js +15 -0
- package/package.json +3 -4
- package/src/app.css +3 -0
- package/src/lib/actions.ts +2 -0
- package/src/lib/components/Studio.svelte +46 -47
- package/src/lib/components/StudioRoot.svelte +19 -0
- package/src/lib/components/breadCrumbs.svelte +5 -4
- package/src/lib/components/codeEditor.svelte +1 -1
- package/src/lib/components/combobox.svelte +3 -3
- package/src/lib/components/confirmationDialog/confirmationDialog.svelte +1 -1
- package/src/lib/components/dataTable/dataTable.svelte +108 -101
- package/src/lib/components/dataTable/dataTableTabs.svelte +4 -2
- package/src/lib/components/dataTable/filter.svelte +1 -1
- package/src/lib/components/dataTable/filterButton.svelte +1 -1
- package/src/lib/components/dataTable/header.svelte +30 -47
- package/src/lib/components/dataTable/listViewChildren.svelte +4 -6
- package/src/lib/components/dataTable/sort.svelte +1 -1
- package/src/lib/components/dataTable/sortButton.svelte +2 -2
- package/src/lib/components/dataTable/table.svelte +8 -10
- package/src/lib/components/dataTableDrawer/dataTableDrawer.svelte +4 -1
- package/src/lib/components/detailView/create/children.svelte +2 -2
- package/src/lib/components/detailView/create/createDetailView.svelte +81 -88
- package/src/lib/components/detailView/create/createDetailViewButton.svelte +2 -2
- package/src/lib/components/detailView/create/createManyView.svelte +12 -10
- package/src/lib/components/detailView/detailView.svelte +81 -0
- package/src/lib/components/detailView/fieldInput.svelte +11 -11
- package/src/lib/components/detailView/fieldInputReplacement.svelte +8 -8
- package/src/lib/components/detailView/passwordInput.svelte +1 -1
- package/src/lib/components/detailView/update/detailViewChildren.svelte +15 -26
- package/src/lib/components/detailView/update/updateDetailView.svelte +90 -69
- package/src/lib/components/detailView/update/updateDetailViewButton.svelte +3 -2
- package/src/lib/components/detailView/utils.ts +13 -0
- package/src/lib/components/diffViewer.svelte +1 -1
- package/src/lib/components/extensionsComponents.svelte +3 -1
- package/src/lib/components/foreingKeyInput.svelte +2 -2
- package/src/lib/components/importButton.svelte +12 -9
- package/src/lib/components/landing.svelte +7 -0
- package/src/lib/components/miniSidebar.svelte +90 -19
- package/src/lib/components/polymorphicInput.svelte +1 -1
- package/src/lib/components/rangeCalendarButton.svelte +13 -13
- package/src/lib/components/richTextEditor.svelte +1 -1
- package/src/lib/components/routes/collections/collection.svelte +3 -3
- package/src/lib/components/routes/collections/collections.svelte +34 -12
- package/src/lib/components/routes/data_model/dataModel.svelte +6 -28
- package/src/lib/components/routes/extensions/extension.svelte +1 -1
- package/src/lib/components/routes/extensions/publicExtension.svelte +19 -0
- package/src/lib/components/routes/home.svelte +3 -3
- package/src/lib/components/routes/workflows/workflows.svelte +9 -9
- package/src/lib/components/selectRecord.svelte +2 -21
- package/src/lib/components/setServerPage.svelte +1 -1
- package/src/lib/components/sidebar/sidebar.svelte +1 -1
- package/src/lib/components/sidebar/sidebarElements.svelte +4 -4
- package/src/lib/components/singletone.svelte +4 -6
- package/src/lib/components/ui/alert-dialog/alert-dialog-action.svelte +1 -1
- package/src/lib/components/ui/alert-dialog/alert-dialog-cancel.svelte +1 -1
- package/src/lib/components/ui/button/button.svelte +2 -3
- package/src/lib/components/ui/command/command-dialog.svelte +1 -1
- package/src/lib/components/ui/range-calendar/range-calendar-day.svelte +1 -1
- package/src/lib/components/ui/range-calendar/range-calendar-next-button.svelte +1 -1
- package/src/lib/components/ui/range-calendar/range-calendar-prev-button.svelte +1 -1
- package/src/lib/components/ui/select/select-separator.svelte +1 -1
- package/src/lib/components/workflowEditor.svelte +5 -5
- package/src/lib/eventSystem.ts +8 -7
- package/src/lib/extensions/extension.types.ts +39 -6
- package/src/lib/extensions/extensionUtils.ts +4 -2
- package/src/lib/index.ts +3 -1
- package/src/lib/store.types.ts +2 -2
- package/src/lib/studioLifecycle.svelte.ts +17 -0
- package/vite-plugins/index.js +2 -4
- package/vite-plugins/utils.js +15 -0
- package/vite-plugins/{workspace-optimize.js → workspace-fs-allow.js} +4 -18
- package/dist/components/routes/data_model/syncManager.svelte +0 -94
- package/dist/components/routes/data_model/syncManager.svelte.d.ts +0 -3
- package/src/lib/components/routes/data_model/syncManager.svelte +0 -94
- package/vite-plugins/contextual-lib-alias.js +0 -67
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import * as Popover from "
|
|
2
|
+
import * as Popover from "../ui/popover/index.js";
|
|
3
3
|
import { ListFilter } from "lucide-svelte";
|
|
4
4
|
import { buttonVariants } from "../ui/button";
|
|
5
5
|
import Filter from "./filter.svelte";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { getStudioContext } from "../../context";
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
import type { Changes, ChildrenChanges } from "../detailView/utils";
|
|
4
|
+
import type { ParentContext } from "./dataTable.svelte";
|
|
5
5
|
import { Download, ListRestart, Plus, Trash, Link } from "lucide-svelte";
|
|
6
6
|
import * as Tooltip from "../ui/tooltip";
|
|
7
7
|
import LlmButton from "../LlmButton.svelte";
|
|
@@ -15,15 +15,17 @@
|
|
|
15
15
|
import ExtensionsComponents from "../extensionsComponents.svelte";
|
|
16
16
|
import { getExtensionUtils } from "../../extensions/extensionUtils";
|
|
17
17
|
import type { Snippet } from "svelte";
|
|
18
|
-
|
|
18
|
+
|
|
19
|
+
const { lobb, ctx } = getStudioContext();
|
|
19
20
|
|
|
20
21
|
interface Props {
|
|
21
22
|
collectionName: string;
|
|
22
23
|
params: any;
|
|
23
24
|
selectedRecords: string[];
|
|
24
25
|
parentContext?: ParentContext;
|
|
25
|
-
|
|
26
|
+
changes?: ChildrenChanges;
|
|
26
27
|
showImport?: boolean;
|
|
28
|
+
showCreate?: boolean;
|
|
27
29
|
left?: Snippet<[]>;
|
|
28
30
|
}
|
|
29
31
|
|
|
@@ -32,37 +34,28 @@
|
|
|
32
34
|
params = $bindable(),
|
|
33
35
|
selectedRecords = $bindable(),
|
|
34
36
|
parentContext,
|
|
35
|
-
|
|
37
|
+
changes,
|
|
36
38
|
showImport = true,
|
|
39
|
+
showCreate = false,
|
|
37
40
|
left
|
|
38
41
|
}: Props = $props();
|
|
39
42
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
{},
|
|
49
|
-
{ [collectionName]: { link: [selected.id] } },
|
|
50
|
-
);
|
|
43
|
+
// Local changes object for the create form (recording mode only)
|
|
44
|
+
let createChanges = $state<Changes>({ data: {}, children: {} });
|
|
45
|
+
|
|
46
|
+
function handleLink(record: any) {
|
|
47
|
+
if (changes) {
|
|
48
|
+
changes.linked.push(record);
|
|
49
|
+
} else if (parentContext) {
|
|
50
|
+
lobb.updateOne(parentContext.collectionName, String(parentContext.recordId), {}, { [collectionName]: { link: [record.id] } });
|
|
51
51
|
resetTable();
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
async function
|
|
56
|
-
if (
|
|
57
|
-
|
|
58
|
-
onOperation({ type: "create", record: formData });
|
|
55
|
+
async function handleCreateSuccess(snap: any) {
|
|
56
|
+
if (changes) {
|
|
57
|
+
changes.created.push({ data: snap.data });
|
|
59
58
|
} else {
|
|
60
|
-
await lobb.updateOne(
|
|
61
|
-
parentContext.collectionName,
|
|
62
|
-
String(parentContext.recordId),
|
|
63
|
-
{},
|
|
64
|
-
{ [collectionName]: { create: [formData] } },
|
|
65
|
-
);
|
|
66
59
|
resetTable();
|
|
67
60
|
}
|
|
68
61
|
}
|
|
@@ -176,7 +169,7 @@
|
|
|
176
169
|
>
|
|
177
170
|
{headerIsSmall ? "" : "Refresh"}
|
|
178
171
|
</Button>
|
|
179
|
-
{#if showImport}
|
|
172
|
+
{#if showImport && showCreate}
|
|
180
173
|
<Tooltip.Provider delayDuration={0}>
|
|
181
174
|
<Tooltip.Root>
|
|
182
175
|
<Tooltip.Trigger>
|
|
@@ -199,34 +192,24 @@
|
|
|
199
192
|
refresh={() => { params = { ...params }; }}
|
|
200
193
|
/>
|
|
201
194
|
{#if parentContext}
|
|
202
|
-
|
|
203
|
-
<SelectRecord
|
|
204
|
-
{collectionName}
|
|
205
|
-
variant="outline"
|
|
206
|
-
class="h-7 px-3 text-xs font-normal"
|
|
207
|
-
Icon={Link}
|
|
208
|
-
onSelect={handleLink}
|
|
209
|
-
>
|
|
210
|
-
{headerIsSmall ? "" : "Link"}
|
|
211
|
-
</SelectRecord>
|
|
212
|
-
{/if}
|
|
213
|
-
<CreateDetailViewButton
|
|
195
|
+
<SelectRecord
|
|
214
196
|
{collectionName}
|
|
215
|
-
variant="
|
|
197
|
+
variant="outline"
|
|
216
198
|
class="h-7 px-3 text-xs font-normal"
|
|
217
|
-
Icon={
|
|
218
|
-
|
|
219
|
-
onSuccessfullSave={handleChildCreate}
|
|
199
|
+
Icon={Link}
|
|
200
|
+
onSelect={handleLink}
|
|
220
201
|
>
|
|
221
|
-
{headerIsSmall ? "" : "
|
|
222
|
-
</
|
|
223
|
-
{
|
|
202
|
+
{headerIsSmall ? "" : "Link"}
|
|
203
|
+
</SelectRecord>
|
|
204
|
+
{/if}
|
|
205
|
+
{#if showCreate}
|
|
224
206
|
<CreateDetailViewButton
|
|
225
207
|
{collectionName}
|
|
226
208
|
variant="default"
|
|
227
209
|
class="h-7 px-3 text-xs font-normal"
|
|
228
210
|
Icon={Plus}
|
|
229
|
-
|
|
211
|
+
changes={changes ? createChanges : undefined}
|
|
212
|
+
onSuccessfullSave={handleCreateSuccess}
|
|
230
213
|
>
|
|
231
214
|
{headerIsSmall ? "" : "Create"}
|
|
232
215
|
</CreateDetailViewButton>
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
+
import type { ChildrenChanges } from "../detailView/utils";
|
|
2
|
+
import type { ParentContext } from "./dataTable.svelte";
|
|
1
3
|
import type { Snippet } from "svelte";
|
|
2
|
-
import type { ParentContext, RecordOperation } from "./dataTable.svelte";
|
|
3
4
|
interface Props {
|
|
4
5
|
collectionName: string;
|
|
5
6
|
params: any;
|
|
6
7
|
selectedRecords: string[];
|
|
7
8
|
parentContext?: ParentContext;
|
|
8
|
-
|
|
9
|
+
changes?: ChildrenChanges;
|
|
9
10
|
showImport?: boolean;
|
|
11
|
+
showCreate?: boolean;
|
|
10
12
|
left?: Snippet<[]>;
|
|
11
13
|
}
|
|
12
14
|
declare const Header: import("svelte").Component<Props, {}, "selectedRecords" | "params">;
|
|
@@ -12,10 +12,9 @@
|
|
|
12
12
|
collectionName: string;
|
|
13
13
|
recordId: string;
|
|
14
14
|
width: number;
|
|
15
|
-
unifiedBgColor?: "bg-muted/30" | "bg-background";
|
|
16
15
|
}
|
|
17
16
|
|
|
18
|
-
let { collectionName, recordId, width
|
|
17
|
+
let { collectionName, recordId, width }: Props = $props();
|
|
19
18
|
|
|
20
19
|
const children = (ctx.meta.collections[collectionName]?.children ?? [])
|
|
21
20
|
.filter((c: any) => c.type === "fk" || c.type === "m2m" || c.type === "polymorphic");
|
|
@@ -27,13 +26,13 @@
|
|
|
27
26
|
|
|
28
27
|
<div class="flex" style="width: {width}px;">
|
|
29
28
|
<div
|
|
30
|
-
class="flex justify-center border-r
|
|
29
|
+
class="flex justify-center border-r bg-background"
|
|
31
30
|
style="width: 40px"
|
|
32
31
|
></div>
|
|
33
32
|
<div class="flex-1 flex flex-col">
|
|
34
33
|
{#each children as child, index}
|
|
35
34
|
{@const lastRow = children.length - 1 === index}
|
|
36
|
-
<div class="overflow-hidden
|
|
35
|
+
<div class="overflow-hidden bg-background">
|
|
37
36
|
<div
|
|
38
37
|
bind:clientWidth={tableHeaderWidth}
|
|
39
38
|
class="flex justify-between items-center gap-2 text-sm h-10 {expandedRows[index] || !lastRow ? 'border-b' : ''}"
|
|
@@ -75,7 +74,7 @@
|
|
|
75
74
|
{#if expandedRows[index]}
|
|
76
75
|
<div class="flex max-h-96 overflow-auto {lastRow ? '' : 'border-b'}">
|
|
77
76
|
<div
|
|
78
|
-
class="border-r
|
|
77
|
+
class="border-r"
|
|
79
78
|
style="width: 100vw; max-width: 40px"
|
|
80
79
|
></div>
|
|
81
80
|
<div class="flex-1" style="width: {tableHeaderWidth - 40}px;">
|
|
@@ -92,7 +91,6 @@
|
|
|
92
91
|
showHeader={false}
|
|
93
92
|
showFooter={false}
|
|
94
93
|
showDelete={child.type === "fk"}
|
|
95
|
-
{unifiedBgColor}
|
|
96
94
|
tableProps={{ showLastRowBorder: false, showLastColumnBorder: false, showCheckboxes: false }}
|
|
97
95
|
/>
|
|
98
96
|
</ExtensionsComponents>
|
|
@@ -2,7 +2,6 @@ interface Props {
|
|
|
2
2
|
collectionName: string;
|
|
3
3
|
recordId: string;
|
|
4
4
|
width: number;
|
|
5
|
-
unifiedBgColor?: "bg-muted/30" | "bg-background";
|
|
6
5
|
}
|
|
7
6
|
declare const ListViewChildren: import("svelte").Component<Props, {}, "">;
|
|
8
7
|
type ListViewChildren = ReturnType<typeof ListViewChildren>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import * as _ from "lodash-es";
|
|
3
3
|
|
|
4
|
-
import * as Popover from "
|
|
4
|
+
import * as Popover from "../ui/popover/index.js";
|
|
5
5
|
import { ArrowDown, ArrowUp, GripVertical, Plus, X } from "lucide-svelte";
|
|
6
6
|
import Button, { buttonVariants } from "../ui/button/button.svelte";
|
|
7
7
|
import Label from "../ui/label/label.svelte";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import * as Popover from "
|
|
2
|
+
import * as Popover from "../ui/popover/index.js";
|
|
3
3
|
import { ArrowDownWideNarrow } from "lucide-svelte";
|
|
4
|
-
import { buttonVariants } from "
|
|
4
|
+
import { buttonVariants } from "../ui/button";
|
|
5
5
|
import Sort from "./sort.svelte";
|
|
6
6
|
|
|
7
7
|
interface Props {
|
|
@@ -38,7 +38,6 @@
|
|
|
38
38
|
|
|
39
39
|
// other
|
|
40
40
|
parentWidth?: number;
|
|
41
|
-
unifiedBgColor?: "bg-muted/30" | "bg-background";
|
|
42
41
|
select?: Select;
|
|
43
42
|
tableWidth?: number;
|
|
44
43
|
}
|
|
@@ -77,7 +76,6 @@
|
|
|
77
76
|
tools,
|
|
78
77
|
rowActions,
|
|
79
78
|
collapsible,
|
|
80
|
-
unifiedBgColor,
|
|
81
79
|
select,
|
|
82
80
|
tableWidth = $bindable(),
|
|
83
81
|
}: TableProps = $props();
|
|
@@ -184,7 +182,7 @@
|
|
|
184
182
|
flex items-center p-2.5 text-xs h-10
|
|
185
183
|
border-r border-b gap-2
|
|
186
184
|
{headerBorderTop ? 'border-t' : ''}
|
|
187
|
-
|
|
185
|
+
bg-muted-soft
|
|
188
186
|
"
|
|
189
187
|
>
|
|
190
188
|
<!-- collapsable toggle -->
|
|
@@ -209,7 +207,7 @@
|
|
|
209
207
|
class="
|
|
210
208
|
sticky top-0 z-10
|
|
211
209
|
flex items-center p-2.5 text-xs h-10
|
|
212
|
-
|
|
210
|
+
bg-muted-soft
|
|
213
211
|
{lastColumn && !showLastColumnBorder ? '' : 'border-r'}
|
|
214
212
|
border-b gap-2
|
|
215
213
|
{headerBorderTop ? 'border-t' : ''}
|
|
@@ -236,7 +234,7 @@
|
|
|
236
234
|
class="
|
|
237
235
|
sticky top-0 right-0 z-20
|
|
238
236
|
flex items-center p-2.5 h-10
|
|
239
|
-
|
|
237
|
+
bg-muted-soft
|
|
240
238
|
border-l border-b
|
|
241
239
|
{headerBorderTop ? 'border-t' : ''}
|
|
242
240
|
"
|
|
@@ -251,7 +249,7 @@
|
|
|
251
249
|
class="
|
|
252
250
|
sticky left-0
|
|
253
251
|
flex items-center p-2.5 text-xs h-10
|
|
254
|
-
|
|
252
|
+
bg-background
|
|
255
253
|
border-r gap-2
|
|
256
254
|
"
|
|
257
255
|
>
|
|
@@ -298,7 +296,7 @@
|
|
|
298
296
|
class="
|
|
299
297
|
flex items-center p-2.5 text-xs h-10 text-nowrap overflow-clip
|
|
300
298
|
{select ? 'cursor-pointer' : ''}
|
|
301
|
-
|
|
299
|
+
bg-background
|
|
302
300
|
{lastColumn && !showLastColumnBorder ? '' : 'border-r'}
|
|
303
301
|
"
|
|
304
302
|
>
|
|
@@ -315,7 +313,7 @@
|
|
|
315
313
|
sticky right-0 z-10
|
|
316
314
|
flex items-center p-2.5 text-xs h-10
|
|
317
315
|
border-l gap-2
|
|
318
|
-
|
|
316
|
+
bg-background
|
|
319
317
|
"
|
|
320
318
|
>
|
|
321
319
|
{@render rowActions?.(entry, index)}
|
|
@@ -336,8 +334,8 @@
|
|
|
336
334
|
{expandedRows[index] ? '' : 'height: 0px;'}
|
|
337
335
|
"
|
|
338
336
|
class="
|
|
339
|
-
sticky left-0 top-0 overflow-auto bg-muted
|
|
340
|
-
|
|
337
|
+
sticky left-0 top-0 overflow-auto bg-muted-soft
|
|
338
|
+
|
|
341
339
|
{expandedRows[index] ? 'border-t' : ''}
|
|
342
340
|
"
|
|
343
341
|
>
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import DataTable from "../dataTable/dataTable.svelte";
|
|
5
5
|
import Drawer from "../drawer.svelte";
|
|
6
6
|
import type { TableProps } from "../dataTable/table.svelte";
|
|
7
|
+
import type { CollectionTab } from "../../store.types";
|
|
7
8
|
|
|
8
9
|
interface Props {
|
|
9
10
|
collectionName: string;
|
|
@@ -13,6 +14,7 @@
|
|
|
13
14
|
showFooter?: boolean;
|
|
14
15
|
tableProps?: Partial<TableProps>;
|
|
15
16
|
position?: "side" | "bottom";
|
|
17
|
+
tabs?: CollectionTab[];
|
|
16
18
|
onClose?: () => void;
|
|
17
19
|
}
|
|
18
20
|
|
|
@@ -24,6 +26,7 @@
|
|
|
24
26
|
showFooter = true,
|
|
25
27
|
tableProps,
|
|
26
28
|
position = "side",
|
|
29
|
+
tabs,
|
|
27
30
|
onClose,
|
|
28
31
|
}: Props = $props();
|
|
29
32
|
</script>
|
|
@@ -47,7 +50,7 @@
|
|
|
47
50
|
{showHeader}
|
|
48
51
|
{showFooter}
|
|
49
52
|
{tableProps}
|
|
50
|
-
|
|
53
|
+
{tabs}
|
|
51
54
|
/>
|
|
52
55
|
</div>
|
|
53
56
|
</Drawer>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { TableProps } from "../dataTable/table.svelte";
|
|
2
|
+
import type { CollectionTab } from "../../store.types";
|
|
2
3
|
interface Props {
|
|
3
4
|
collectionName: string;
|
|
4
5
|
filter?: Record<string, any>;
|
|
@@ -7,6 +8,7 @@ interface Props {
|
|
|
7
8
|
showFooter?: boolean;
|
|
8
9
|
tableProps?: Partial<TableProps>;
|
|
9
10
|
position?: "side" | "bottom";
|
|
11
|
+
tabs?: CollectionTab[];
|
|
10
12
|
onClose?: () => void;
|
|
11
13
|
}
|
|
12
14
|
declare const DataTableDrawer: import("svelte").Component<Props, {}, "">;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { getStudioContext } from "../../../context";
|
|
3
3
|
import { Link } from "lucide-svelte";
|
|
4
4
|
import CreateManyView from "./createManyView.svelte";
|
|
5
|
-
import ExtensionsComponents from "
|
|
5
|
+
import ExtensionsComponents from "../../extensionsComponents.svelte";
|
|
6
6
|
import { getExtensionUtils } from "../../../extensions/extensionUtils";
|
|
7
7
|
|
|
8
8
|
const { ctx, lobb } = getStudioContext();
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
parentCollectionName={collectionName}
|
|
38
38
|
collectionName={child.collection}
|
|
39
39
|
parentRecord={{ id: entry.id, collectionName }}
|
|
40
|
-
class="bg-muted
|
|
40
|
+
class="bg-muted-soft border rounded-md overflow-hidden"
|
|
41
41
|
bind:value={entry[child.collection]}
|
|
42
42
|
>
|
|
43
43
|
<CreateManyView
|
|
@@ -8,114 +8,142 @@
|
|
|
8
8
|
collectionName: string;
|
|
9
9
|
values?: Record<string, any>;
|
|
10
10
|
showRelatedRecords?: boolean;
|
|
11
|
-
rollback?: boolean;
|
|
12
11
|
submitButton?: SubmitButton;
|
|
13
12
|
title?: Snippet<[string]>;
|
|
14
13
|
onSuccessfullSave?: (entry: any) => Promise<void>;
|
|
15
14
|
onCancel?: () => Promise<void>;
|
|
15
|
+
changes?: import("../utils").Changes | undefined;
|
|
16
16
|
}
|
|
17
17
|
</script>
|
|
18
18
|
|
|
19
19
|
<script lang="ts">
|
|
20
20
|
import { ArrowLeft, Plus, X } from "lucide-svelte";
|
|
21
|
-
import Button from "
|
|
21
|
+
import Button from "../../ui/button/button.svelte";
|
|
22
22
|
import { getStudioContext } from "../../../context";
|
|
23
23
|
import { toast } from "svelte-sonner";
|
|
24
|
+
import { untrack } from "svelte";
|
|
24
25
|
|
|
25
26
|
const { lobb, ctx } = getStudioContext();
|
|
26
|
-
import ExtensionsComponents from "../../extensionsComponents.svelte";
|
|
27
|
-
import { getExtensionUtils } from "../../../extensions/extensionUtils";
|
|
28
|
-
import { getField, getFieldIcon } from "../../dataTable/utils";
|
|
29
27
|
import Children from "./children.svelte";
|
|
30
|
-
import {
|
|
31
|
-
|
|
32
|
-
getDefaultEntry,
|
|
33
|
-
} from "../utils";
|
|
28
|
+
import { buildChildren, getDefaultEntry } from "../utils";
|
|
29
|
+
import type { Changes } from "../utils";
|
|
34
30
|
import { getChangedProperties } from "../../../utils";
|
|
35
31
|
import type { Snippet } from "svelte";
|
|
36
|
-
import
|
|
37
|
-
import
|
|
38
|
-
import Drawer from "../../../components/drawer.svelte";
|
|
32
|
+
import DetailView from "../detailView.svelte";
|
|
33
|
+
import Drawer from "../../drawer.svelte";
|
|
39
34
|
|
|
40
35
|
let {
|
|
41
36
|
collectionName,
|
|
42
|
-
values = {},
|
|
37
|
+
values: passedValues = {} as Record<string, any>,
|
|
43
38
|
showRelatedRecords = true,
|
|
44
|
-
rollback = false,
|
|
45
39
|
onCancel,
|
|
46
40
|
onSuccessfullSave,
|
|
47
41
|
title,
|
|
48
42
|
submitButton,
|
|
43
|
+
changes: passedChanges = $bindable<Changes | undefined>(undefined),
|
|
49
44
|
}: CreateDetailViewProp = $props();
|
|
50
45
|
|
|
46
|
+
const isRecordingMode = passedChanges !== undefined;
|
|
47
|
+
if (!isRecordingMode) passedChanges = { data: {}, children: {} };
|
|
48
|
+
const changes = passedChanges as Changes;
|
|
49
|
+
|
|
51
50
|
const fieldNames = Object.keys(ctx.meta.collections[collectionName].fields);
|
|
52
|
-
let
|
|
53
|
-
getDefaultEntry(ctx, fieldNames, collectionName, values),
|
|
54
|
-
);
|
|
55
|
-
const initialEntry = $state.snapshot(entry);
|
|
51
|
+
let values = $state(getDefaultEntry(ctx, fieldNames, collectionName, passedValues));
|
|
56
52
|
let fieldsErrors: Record<string, any> = $state({});
|
|
57
|
-
|
|
53
|
+
|
|
54
|
+
const childCollections = ctx.meta.relations
|
|
55
|
+
.filter((r) => r.to.collection === collectionName)
|
|
56
|
+
.map((r) => (r as any).from.collection);
|
|
57
|
+
|
|
58
58
|
const subCollectionsValues: Record<string, any> = {};
|
|
59
|
-
for (
|
|
60
|
-
|
|
61
|
-
if (values[subCollection]) {
|
|
62
|
-
subCollectionsValues[subCollection] = values[subCollection];
|
|
63
|
-
}
|
|
59
|
+
for (const col of childCollections) {
|
|
60
|
+
if (passedValues[col]) subCollectionsValues[col] = passedValues[col];
|
|
64
61
|
}
|
|
65
62
|
|
|
66
|
-
|
|
67
|
-
|
|
63
|
+
$effect(() => {
|
|
64
|
+
const snap = $state.snapshot(values);
|
|
68
65
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
});
|
|
66
|
+
untrack(() => {
|
|
67
|
+
const data: Record<string, any> = {};
|
|
68
|
+
const children: Record<string, any> = {};
|
|
73
69
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
70
|
+
for (const [key, value] of Object.entries(snap)) {
|
|
71
|
+
if (childCollections.includes(key) && Array.isArray(value)) {
|
|
72
|
+
children[key] = {
|
|
73
|
+
created: (value as any[]).filter((r) => !r.id).map((r) => ({ data: r })),
|
|
74
|
+
updated: [],
|
|
75
|
+
deleted: [],
|
|
76
|
+
linked: (value as any[]).filter((r) => r.id).map((r) => r.id),
|
|
77
|
+
unlinked: [],
|
|
78
|
+
};
|
|
79
|
+
} else if (value !== null && value !== undefined && value !== '') {
|
|
80
|
+
data[key] = value;
|
|
81
|
+
}
|
|
78
82
|
}
|
|
79
|
-
}
|
|
80
83
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
84
|
+
changes.data = data;
|
|
85
|
+
changes.children = children;
|
|
86
|
+
|
|
87
|
+
if (!isRecordingMode) {
|
|
88
|
+
console.log(`[${collectionName}] changes:`, $state.snapshot(changes));
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
function handleCancel() {
|
|
94
|
+
if (isRecordingMode) {
|
|
95
|
+
changes.data = {};
|
|
96
|
+
changes.children = {};
|
|
85
97
|
}
|
|
98
|
+
onCancel?.();
|
|
99
|
+
}
|
|
86
100
|
|
|
87
|
-
|
|
88
|
-
const
|
|
101
|
+
async function handleSave() {
|
|
102
|
+
const snap = $state.snapshot(changes);
|
|
89
103
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
104
|
+
const children = buildChildren(ctx, collectionName, { ...snap.data, ...Object.fromEntries(
|
|
105
|
+
Object.entries(snap.children).map(([col, ops]) => [
|
|
106
|
+
col,
|
|
107
|
+
[
|
|
108
|
+
...(ops.created.map((op) => op.data)),
|
|
109
|
+
...(ops.linked.map((id) => ({ id }))),
|
|
110
|
+
]
|
|
111
|
+
])
|
|
112
|
+
)});
|
|
113
|
+
|
|
114
|
+
const response = await lobb.createOne(collectionName, snap.data, children, undefined, isRecordingMode);
|
|
115
|
+
|
|
116
|
+
if (response.status === 204) {
|
|
117
|
+
if (onSuccessfullSave) await onSuccessfullSave(snap);
|
|
118
|
+
toast.success(`The record was successfully created`);
|
|
119
|
+
handleCancel();
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
95
122
|
|
|
96
123
|
if (!response.bodyUsed) {
|
|
97
|
-
|
|
124
|
+
const result = await response.json();
|
|
98
125
|
if (response.status >= 400) {
|
|
99
126
|
if (result.message && result.details) {
|
|
100
127
|
fieldsErrors = result.details;
|
|
101
128
|
return;
|
|
102
129
|
} else if (result.message) {
|
|
130
|
+
toast.error(result.message);
|
|
103
131
|
return;
|
|
104
132
|
}
|
|
105
133
|
}
|
|
106
134
|
}
|
|
107
135
|
|
|
108
|
-
if (onSuccessfullSave) await onSuccessfullSave(
|
|
136
|
+
if (onSuccessfullSave) await onSuccessfullSave(snap);
|
|
109
137
|
toast.success(`The record was successfully created`);
|
|
110
138
|
onCancel?.();
|
|
111
139
|
}
|
|
112
140
|
</script>
|
|
113
141
|
|
|
114
|
-
<Drawer onHide={
|
|
142
|
+
<Drawer onHide={handleCancel}>
|
|
115
143
|
<div class="flex h-12 items-center gap-4 border-b px-4">
|
|
116
144
|
<Button
|
|
117
145
|
variant="outline"
|
|
118
|
-
onclick={
|
|
146
|
+
onclick={handleCancel}
|
|
119
147
|
class=" h-8 w-8 rounded-full text-xs font-normal"
|
|
120
148
|
Icon={ArrowLeft}
|
|
121
149
|
></Button>
|
|
@@ -131,51 +159,16 @@
|
|
|
131
159
|
</div>
|
|
132
160
|
</div>
|
|
133
161
|
<div class="flex-1 overflow-y-auto">
|
|
134
|
-
<
|
|
135
|
-
{#each fieldNames as fieldName}
|
|
136
|
-
{#if !ctx.meta.collections[collectionName].fields[fieldName]?.ui?.hidden}
|
|
137
|
-
{@const field = getField(ctx, fieldName, collectionName)}
|
|
138
|
-
{@const FieldIcon = getFieldIcon(ctx, fieldName, collectionName)}
|
|
139
|
-
<div class="flex flex-col gap-2">
|
|
140
|
-
<div class="flex flex-1 items-end justify-between gap-2 text-xs">
|
|
141
|
-
<div class="flex gap-2">
|
|
142
|
-
<div class="h-fit">{field.label}</div>
|
|
143
|
-
<div class="flex h-fit items-center gap-1 text-[0.7rem] text-muted-foreground">
|
|
144
|
-
<FieldIcon size="12" />
|
|
145
|
-
{field.type}
|
|
146
|
-
</div>
|
|
147
|
-
</div>
|
|
148
|
-
<div>
|
|
149
|
-
<ExtensionsComponents
|
|
150
|
-
name="dvFields.topRight.{collectionName}.{fieldName}"
|
|
151
|
-
utils={getExtensionUtils(lobb, ctx)}
|
|
152
|
-
bind:value={entry[fieldName]}
|
|
153
|
-
/>
|
|
154
|
-
</div>
|
|
155
|
-
</div>
|
|
156
|
-
<FieldInput
|
|
157
|
-
{collectionName}
|
|
158
|
-
{fieldName}
|
|
159
|
-
bind:value={
|
|
160
|
-
() => entry[fieldName],
|
|
161
|
-
(v) => (entry = { ...entry, [fieldName]: v })
|
|
162
|
-
}
|
|
163
|
-
bind:entry
|
|
164
|
-
errorMessages={fieldsErrors[fieldName]}
|
|
165
|
-
/>
|
|
166
|
-
</div>
|
|
167
|
-
{/if}
|
|
168
|
-
{/each}
|
|
169
|
-
</div>
|
|
162
|
+
<DetailView {collectionName} bind:entry={values} {fieldsErrors} />
|
|
170
163
|
{#if showRelatedRecords}
|
|
171
|
-
<Children {collectionName} values={subCollectionsValues} bind:entry />
|
|
164
|
+
<Children {collectionName} values={subCollectionsValues} bind:entry={values} />
|
|
172
165
|
{/if}
|
|
173
166
|
</div>
|
|
174
167
|
<div class="flex h-12 items-center justify-end gap-2 border-t px-4">
|
|
175
168
|
<div class="flex gap-3">
|
|
176
169
|
<Button
|
|
177
170
|
variant="outline"
|
|
178
|
-
onclick={
|
|
171
|
+
onclick={handleCancel}
|
|
179
172
|
class="h-7 px-3 text-xs font-normal"
|
|
180
173
|
Icon={X}
|
|
181
174
|
>
|