@lobb-js/studio 0.28.5 → 0.29.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/components/Studio.svelte +7 -4
- package/dist/components/combobox.svelte +3 -3
- package/dist/components/confirmationDialog/confirmationDialog.svelte +1 -1
- package/dist/components/dataTable/dataTable.svelte +74 -82
- package/dist/components/dataTable/dataTable.svelte.d.ts +3 -19
- package/dist/components/dataTable/filter.svelte +1 -1
- package/dist/components/dataTable/filterButton.svelte +1 -1
- package/dist/components/dataTable/header.svelte +33 -54
- package/dist/components/dataTable/header.svelte.d.ts +3 -2
- package/dist/components/dataTable/sort.svelte +1 -1
- package/dist/components/dataTable/sortButton.svelte +2 -2
- package/dist/components/detailView/create/children.svelte +1 -1
- package/dist/components/detailView/create/createDetailView.svelte +77 -42
- 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 +10 -6
- package/dist/components/detailView/fieldInput.svelte +1 -1
- package/dist/components/detailView/fieldInputReplacement.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 +85 -27
- 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/miniSidebar.svelte +4 -4
- package/dist/components/rangeCalendarButton.svelte +3 -3
- package/dist/components/routes/collections/collection.svelte +3 -3
- package/dist/components/routes/collections/collections.svelte +2 -2
- package/dist/components/routes/data_model/dataModel.svelte +2 -2
- package/dist/components/routes/data_model/syncManager.svelte +4 -4
- package/dist/components/routes/extensions/extension.svelte +1 -1
- package/dist/components/routes/home.svelte +1 -1
- package/dist/components/routes/workflows/workflows.svelte +5 -5
- package/dist/components/selectRecord.svelte +2 -21
- package/dist/components/setServerPage.svelte +1 -1
- 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/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 +3 -3
- package/dist/store.types.d.ts +1 -1
- package/package.json +2 -2
- package/src/lib/components/Studio.svelte +7 -4
- package/src/lib/components/combobox.svelte +3 -3
- package/src/lib/components/confirmationDialog/confirmationDialog.svelte +1 -1
- package/src/lib/components/dataTable/dataTable.svelte +74 -82
- 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 +33 -54
- package/src/lib/components/dataTable/sort.svelte +1 -1
- package/src/lib/components/dataTable/sortButton.svelte +2 -2
- package/src/lib/components/detailView/create/children.svelte +1 -1
- package/src/lib/components/detailView/create/createDetailView.svelte +77 -42
- package/src/lib/components/detailView/create/createDetailViewButton.svelte +2 -2
- package/src/lib/components/detailView/create/createManyView.svelte +10 -6
- package/src/lib/components/detailView/fieldInput.svelte +1 -1
- package/src/lib/components/detailView/fieldInputReplacement.svelte +1 -1
- package/src/lib/components/detailView/update/detailViewChildren.svelte +15 -26
- package/src/lib/components/detailView/update/updateDetailView.svelte +85 -27
- package/src/lib/components/detailView/update/updateDetailViewButton.svelte +3 -2
- package/src/lib/components/detailView/utils.ts +13 -0
- package/src/lib/components/miniSidebar.svelte +4 -4
- package/src/lib/components/rangeCalendarButton.svelte +3 -3
- package/src/lib/components/routes/collections/collection.svelte +3 -3
- package/src/lib/components/routes/collections/collections.svelte +2 -2
- package/src/lib/components/routes/data_model/dataModel.svelte +2 -2
- package/src/lib/components/routes/data_model/syncManager.svelte +4 -4
- package/src/lib/components/routes/extensions/extension.svelte +1 -1
- package/src/lib/components/routes/home.svelte +1 -1
- package/src/lib/components/routes/workflows/workflows.svelte +5 -5
- package/src/lib/components/selectRecord.svelte +2 -21
- package/src/lib/components/setServerPage.svelte +1 -1
- 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/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 +3 -3
- package/src/lib/store.types.ts +1 -1
- package/vite-plugins/index.js +2 -4
- package/vite-plugins/lobb-extensions.js +12 -0
- package/vite-plugins/utils.js +15 -0
- package/vite-plugins/workspace-fs-allow.js +33 -0
- package/vite-plugins/contextual-lib-alias.js +0 -67
- package/vite-plugins/workspace-optimize.js +0 -106
|
@@ -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,14 +15,15 @@
|
|
|
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;
|
|
27
28
|
left?: Snippet<[]>;
|
|
28
29
|
}
|
|
@@ -32,37 +33,27 @@
|
|
|
32
33
|
params = $bindable(),
|
|
33
34
|
selectedRecords = $bindable(),
|
|
34
35
|
parentContext,
|
|
35
|
-
|
|
36
|
+
changes,
|
|
36
37
|
showImport = true,
|
|
37
38
|
left
|
|
38
39
|
}: Props = $props();
|
|
39
40
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
{},
|
|
49
|
-
{ [collectionName]: { link: [selected.id] } },
|
|
50
|
-
);
|
|
41
|
+
// Local changes object for the create form (recording mode only)
|
|
42
|
+
let createChanges = $state<Changes>({ data: {}, children: {} });
|
|
43
|
+
|
|
44
|
+
function handleLink(record: any) {
|
|
45
|
+
if (changes) {
|
|
46
|
+
changes.linked.push(record);
|
|
47
|
+
} else if (parentContext) {
|
|
48
|
+
lobb.updateOne(parentContext.collectionName, String(parentContext.recordId), {}, { [collectionName]: { link: [record.id] } });
|
|
51
49
|
resetTable();
|
|
52
50
|
}
|
|
53
51
|
}
|
|
54
52
|
|
|
55
|
-
async function
|
|
56
|
-
if (
|
|
57
|
-
|
|
58
|
-
onOperation({ type: "create", record: formData });
|
|
53
|
+
async function handleCreateSuccess(snap: any) {
|
|
54
|
+
if (changes) {
|
|
55
|
+
changes.created.push({ data: snap.data });
|
|
59
56
|
} else {
|
|
60
|
-
await lobb.updateOne(
|
|
61
|
-
parentContext.collectionName,
|
|
62
|
-
String(parentContext.recordId),
|
|
63
|
-
{},
|
|
64
|
-
{ [collectionName]: { create: [formData] } },
|
|
65
|
-
);
|
|
66
57
|
resetTable();
|
|
67
58
|
}
|
|
68
59
|
}
|
|
@@ -199,37 +190,25 @@
|
|
|
199
190
|
refresh={() => { params = { ...params }; }}
|
|
200
191
|
/>
|
|
201
192
|
{#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
|
|
193
|
+
<SelectRecord
|
|
214
194
|
{collectionName}
|
|
215
|
-
variant="
|
|
216
|
-
class="h-7 px-3 text-xs font-normal"
|
|
217
|
-
Icon={Plus}
|
|
218
|
-
rollback={true}
|
|
219
|
-
onSuccessfullSave={handleChildCreate}
|
|
220
|
-
>
|
|
221
|
-
{headerIsSmall ? "" : "Create"}
|
|
222
|
-
</CreateDetailViewButton>
|
|
223
|
-
{:else}
|
|
224
|
-
<CreateDetailViewButton
|
|
225
|
-
{collectionName}
|
|
226
|
-
variant="default"
|
|
195
|
+
variant="outline"
|
|
227
196
|
class="h-7 px-3 text-xs font-normal"
|
|
228
|
-
Icon={
|
|
229
|
-
|
|
197
|
+
Icon={Link}
|
|
198
|
+
onSelect={handleLink}
|
|
230
199
|
>
|
|
231
|
-
{headerIsSmall ? "" : "
|
|
232
|
-
</
|
|
200
|
+
{headerIsSmall ? "" : "Link"}
|
|
201
|
+
</SelectRecord>
|
|
233
202
|
{/if}
|
|
203
|
+
<CreateDetailViewButton
|
|
204
|
+
{collectionName}
|
|
205
|
+
variant="default"
|
|
206
|
+
class="h-7 px-3 text-xs font-normal"
|
|
207
|
+
Icon={Plus}
|
|
208
|
+
changes={changes ? createChanges : undefined}
|
|
209
|
+
onSuccessfullSave={handleCreateSuccess}
|
|
210
|
+
>
|
|
211
|
+
{headerIsSmall ? "" : "Create"}
|
|
212
|
+
</CreateDetailViewButton>
|
|
234
213
|
</div>
|
|
235
214
|
</div>
|
|
@@ -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 {
|
|
@@ -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();
|
|
@@ -8,93 +8,128 @@
|
|
|
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
27
|
import ExtensionsComponents from "../../extensionsComponents.svelte";
|
|
27
28
|
import { getExtensionUtils } from "../../../extensions/extensionUtils";
|
|
28
29
|
import { getField, getFieldIcon } from "../../dataTable/utils";
|
|
29
30
|
import Children from "./children.svelte";
|
|
30
|
-
import {
|
|
31
|
-
|
|
32
|
-
getDefaultEntry,
|
|
33
|
-
} from "../utils";
|
|
31
|
+
import { buildChildren, getDefaultEntry } from "../utils";
|
|
32
|
+
import type { Changes } from "../utils";
|
|
34
33
|
import { getChangedProperties } from "../../../utils";
|
|
35
34
|
import type { Snippet } from "svelte";
|
|
36
35
|
import FieldInput from "../fieldInput.svelte";
|
|
37
|
-
import
|
|
38
|
-
import Drawer from "../../../components/drawer.svelte";
|
|
36
|
+
import Drawer from "../../drawer.svelte";
|
|
39
37
|
|
|
40
38
|
let {
|
|
41
39
|
collectionName,
|
|
42
40
|
values = {},
|
|
43
41
|
showRelatedRecords = true,
|
|
44
|
-
rollback = false,
|
|
45
42
|
onCancel,
|
|
46
43
|
onSuccessfullSave,
|
|
47
44
|
title,
|
|
48
45
|
submitButton,
|
|
46
|
+
changes = $bindable<Changes | undefined>(undefined),
|
|
49
47
|
}: CreateDetailViewProp = $props();
|
|
50
48
|
|
|
49
|
+
let _changes = $state<Changes>({ data: {}, children: {} });
|
|
50
|
+
const isRecordingMode = $derived(changes !== undefined);
|
|
51
|
+
|
|
51
52
|
const fieldNames = Object.keys(ctx.meta.collections[collectionName].fields);
|
|
52
53
|
let entry: Record<string, any> = $state(
|
|
53
54
|
getDefaultEntry(ctx, fieldNames, collectionName, values),
|
|
54
55
|
);
|
|
55
56
|
const initialEntry = $state.snapshot(entry);
|
|
56
57
|
let fieldsErrors: Record<string, any> = $state({});
|
|
57
|
-
|
|
58
|
+
|
|
59
|
+
const childCollections = ctx.meta.relations
|
|
60
|
+
.filter((r) => r.to.collection === collectionName)
|
|
61
|
+
.map((r) => (r as any).from.collection);
|
|
62
|
+
|
|
63
|
+
const subCollections = childCollections;
|
|
58
64
|
const subCollectionsValues: Record<string, any> = {};
|
|
59
|
-
for (
|
|
60
|
-
|
|
61
|
-
if (values[subCollection]) {
|
|
62
|
-
subCollectionsValues[subCollection] = values[subCollection];
|
|
63
|
-
}
|
|
65
|
+
for (const col of subCollections) {
|
|
66
|
+
if (values[col]) subCollectionsValues[col] = values[col];
|
|
64
67
|
}
|
|
65
68
|
|
|
66
|
-
|
|
67
|
-
|
|
69
|
+
$effect(() => {
|
|
70
|
+
const snap = $state.snapshot(entry);
|
|
68
71
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
72
|
+
untrack(() => {
|
|
73
|
+
const target = changes ?? _changes;
|
|
74
|
+
const data: Record<string, any> = {};
|
|
75
|
+
const children: Record<string, any> = {};
|
|
73
76
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
77
|
+
for (const [key, value] of Object.entries(snap)) {
|
|
78
|
+
if (childCollections.includes(key) && Array.isArray(value)) {
|
|
79
|
+
children[key] = {
|
|
80
|
+
created: (value as any[]).filter((r) => !r.id).map((r) => ({ data: r })),
|
|
81
|
+
updated: [],
|
|
82
|
+
deleted: [],
|
|
83
|
+
linked: (value as any[]).filter((r) => r.id).map((r) => r.id),
|
|
84
|
+
unlinked: [],
|
|
85
|
+
};
|
|
86
|
+
} else if (value !== null && value !== undefined && value !== '') {
|
|
87
|
+
data[key] = value;
|
|
88
|
+
}
|
|
78
89
|
}
|
|
79
|
-
}
|
|
80
90
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
91
|
+
target.data = data;
|
|
92
|
+
target.children = children;
|
|
93
|
+
|
|
94
|
+
if (!isRecordingMode) {
|
|
95
|
+
console.log(`[${collectionName}] changes:`, $state.snapshot(target));
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
function handleCancel() {
|
|
101
|
+
if (changes !== undefined) {
|
|
102
|
+
changes.data = {};
|
|
103
|
+
changes.children = {};
|
|
85
104
|
}
|
|
105
|
+
onCancel?.();
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async function handleSave() {
|
|
109
|
+
const target = changes ?? _changes;
|
|
110
|
+
const snap = $state.snapshot(target);
|
|
86
111
|
|
|
87
|
-
const children = buildChildren(ctx, collectionName,
|
|
88
|
-
|
|
112
|
+
const children = buildChildren(ctx, collectionName, { ...snap.data, ...Object.fromEntries(
|
|
113
|
+
Object.entries(snap.children).map(([col, ops]) => [
|
|
114
|
+
col,
|
|
115
|
+
[
|
|
116
|
+
...(ops.created.map((c) => c.data)),
|
|
117
|
+
...(ops.linked.map((id) => ({ id }))),
|
|
118
|
+
]
|
|
119
|
+
])
|
|
120
|
+
)});
|
|
89
121
|
|
|
90
|
-
await
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
122
|
+
const response = await lobb.createOne(collectionName, snap.data, children, undefined, isRecordingMode);
|
|
123
|
+
|
|
124
|
+
if (response.status === 204) {
|
|
125
|
+
if (onSuccessfullSave) await onSuccessfullSave(snap);
|
|
126
|
+
toast.success(`The record was successfully created`);
|
|
127
|
+
handleCancel();
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
95
130
|
|
|
96
131
|
if (!response.bodyUsed) {
|
|
97
|
-
|
|
132
|
+
const result = await response.json();
|
|
98
133
|
if (response.status >= 400) {
|
|
99
134
|
if (result.message && result.details) {
|
|
100
135
|
fieldsErrors = result.details;
|
|
@@ -105,17 +140,17 @@
|
|
|
105
140
|
}
|
|
106
141
|
}
|
|
107
142
|
|
|
108
|
-
if (onSuccessfullSave) await onSuccessfullSave(
|
|
143
|
+
if (onSuccessfullSave) await onSuccessfullSave(snap);
|
|
109
144
|
toast.success(`The record was successfully created`);
|
|
110
145
|
onCancel?.();
|
|
111
146
|
}
|
|
112
147
|
</script>
|
|
113
148
|
|
|
114
|
-
<Drawer onHide={
|
|
149
|
+
<Drawer onHide={handleCancel}>
|
|
115
150
|
<div class="flex h-12 items-center gap-4 border-b px-4">
|
|
116
151
|
<Button
|
|
117
152
|
variant="outline"
|
|
118
|
-
onclick={
|
|
153
|
+
onclick={handleCancel}
|
|
119
154
|
class=" h-8 w-8 rounded-full text-xs font-normal"
|
|
120
155
|
Icon={ArrowLeft}
|
|
121
156
|
></Button>
|
|
@@ -175,7 +210,7 @@
|
|
|
175
210
|
<div class="flex gap-3">
|
|
176
211
|
<Button
|
|
177
212
|
variant="outline"
|
|
178
|
-
onclick={
|
|
213
|
+
onclick={handleCancel}
|
|
179
214
|
class="h-7 px-3 text-xs font-normal"
|
|
180
215
|
Icon={X}
|
|
181
216
|
>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { CreateDetailViewProp } from "./createDetailView.svelte";
|
|
3
|
-
import type { ButtonProps } from "
|
|
4
|
-
import Button from "
|
|
3
|
+
import type { ButtonProps } from "../../ui/button/button.svelte";
|
|
4
|
+
import Button from "../../ui/button/button.svelte";
|
|
5
5
|
import CreateDetailView from "./createDetailView.svelte";
|
|
6
6
|
|
|
7
7
|
interface LocalProp extends CreateDetailViewProp {
|
|
@@ -11,11 +11,15 @@
|
|
|
11
11
|
import Table, { type TableProps } from "../../dataTable/table.svelte";
|
|
12
12
|
import Button from "../../ui/button/button.svelte";
|
|
13
13
|
import CreateDetailViewButton from "./createDetailViewButton.svelte";
|
|
14
|
-
import {
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
import type { Changes } from "../utils";
|
|
15
|
+
|
|
16
|
+
let addChanges = $state<Changes>({ data: {}, children: {} });
|
|
17
|
+
let editChanges = $state<Changes>({ data: {}, children: {} });
|
|
18
|
+
import { getCollectionColumns } from "../../dataTable/utils";
|
|
19
|
+
import SelectRecord from "../../selectRecord.svelte";
|
|
20
|
+
import FieldCell from "../../dataTable/fieldCell.svelte";
|
|
17
21
|
import SubRecords from "./subRecords.svelte";
|
|
18
|
-
import ListViewChildren from "
|
|
22
|
+
import ListViewChildren from "../../dataTable/listViewChildren.svelte";
|
|
19
23
|
import { getStudioContext } from "../../../context";
|
|
20
24
|
|
|
21
25
|
const { ctx } = getStudioContext();
|
|
@@ -141,7 +145,7 @@
|
|
|
141
145
|
class="h-7 px-2 font-normal text-xs"
|
|
142
146
|
Icon={Plus}
|
|
143
147
|
{collectionName}
|
|
144
|
-
|
|
148
|
+
changes={addChanges}
|
|
145
149
|
showRelatedRecords={true}
|
|
146
150
|
onSuccessfullSave={onRecordAdd}
|
|
147
151
|
values={createValues}
|
|
@@ -197,7 +201,7 @@
|
|
|
197
201
|
class="h-6 w-6 text-muted-foreground hover:bg-transparent p-0"
|
|
198
202
|
Icon={Pencil}
|
|
199
203
|
{collectionName}
|
|
200
|
-
|
|
204
|
+
changes={editChanges}
|
|
201
205
|
showRelatedRecords={true}
|
|
202
206
|
onSuccessfullSave={(entry) =>
|
|
203
207
|
onRecordOverride(entry, index)}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import Button from "../ui/button/button.svelte";
|
|
7
7
|
import FieldCustomInput from "./fieldCustomInput.svelte";
|
|
8
8
|
import Input from "../ui/input/input.svelte";
|
|
9
|
-
import * as Select from "
|
|
9
|
+
import * as Select from "../ui/select/index";
|
|
10
10
|
import EnumBadge from "../dataTable/enumBadge.svelte";
|
|
11
11
|
import type { EnumOption } from "@lobb-js/core";
|
|
12
12
|
import Textarea from "../ui/textarea/textarea.svelte";
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { Ban, Check, CircleAlert, X } from "lucide-svelte";
|
|
3
3
|
import Button from "../ui/button/button.svelte";
|
|
4
4
|
import Input from "../ui/input/input.svelte";
|
|
5
|
-
import * as Select from "
|
|
5
|
+
import * as Select from "../ui/select/index";
|
|
6
6
|
import Textarea from "../ui/textarea/textarea.svelte";
|
|
7
7
|
import type { EntryField } from "./detailViewForm.svelte";
|
|
8
8
|
import type { Snippet } from "svelte";
|
|
@@ -1,43 +1,32 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import DataTable
|
|
2
|
+
import DataTable from "../../dataTable/dataTable.svelte";
|
|
3
3
|
import { getStudioContext } from "../../../context";
|
|
4
4
|
import { Table, Link } from "lucide-svelte";
|
|
5
5
|
|
|
6
6
|
const { ctx } = getStudioContext();
|
|
7
7
|
|
|
8
|
-
type
|
|
9
|
-
link?: (string | number)[];
|
|
10
|
-
unlink?: (string | number)[];
|
|
11
|
-
delete?: (string | number)[];
|
|
12
|
-
create?: any[];
|
|
13
|
-
};
|
|
8
|
+
import type { Changes, ChildrenChanges } from "../utils";
|
|
14
9
|
|
|
15
10
|
interface LocalProp {
|
|
16
11
|
collectionName: string;
|
|
17
12
|
entry: any;
|
|
18
|
-
|
|
13
|
+
activeChanges?: Changes;
|
|
19
14
|
}
|
|
20
15
|
|
|
21
|
-
let { collectionName, entry,
|
|
22
|
-
|
|
23
|
-
function makeHandler(collection: string) {
|
|
24
|
-
return (op: RecordOperation) => {
|
|
25
|
-
if (!pendingChildren[collection]) pendingChildren[collection] = {};
|
|
26
|
-
const c = pendingChildren[collection];
|
|
27
|
-
if (op.type === "link") {
|
|
28
|
-
(c.link ??= []).push(op.record.id);
|
|
29
|
-
} else if (op.type === "unlink") {
|
|
30
|
-
(c.unlink ??= []).push(op.id);
|
|
31
|
-
} else if (op.type === "delete") {
|
|
32
|
-
(c.delete ??= []).push(op.id);
|
|
33
|
-
} else if (op.type === "create") {
|
|
34
|
-
(c.create ??= []).push(op.record);
|
|
35
|
-
}
|
|
36
|
-
};
|
|
37
|
-
}
|
|
16
|
+
let { collectionName, entry, activeChanges }: LocalProp = $props();
|
|
38
17
|
|
|
39
18
|
const children = (ctx.meta.collections[collectionName]?.children ?? [])
|
|
40
19
|
.filter((c: any) => c.type === "fk" || c.type === "m2m" || c.type === "polymorphic");
|
|
20
|
+
|
|
21
|
+
// Ensure all child collection slots exist before the template renders so bind:changes works
|
|
22
|
+
$effect.pre(() => {
|
|
23
|
+
if (!activeChanges) return;
|
|
24
|
+
for (const child of children) {
|
|
25
|
+
if (!activeChanges.children[child.collection]) {
|
|
26
|
+
activeChanges.children[child.collection] = { created: [], updated: [], deleted: [], linked: [], unlinked: [] };
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
});
|
|
41
30
|
</script>
|
|
42
31
|
|
|
43
32
|
{#if children.length}
|
|
@@ -52,7 +41,7 @@
|
|
|
52
41
|
collectionName={child.collection}
|
|
53
42
|
searchParams={{ children_of: collectionName, parent_id: entry.id }}
|
|
54
43
|
parentContext={{ collectionName, recordId: entry.id }}
|
|
55
|
-
|
|
44
|
+
bind:changes={activeChanges!.children[child.collection]}
|
|
56
45
|
showImport={false}
|
|
57
46
|
showHeader={true}
|
|
58
47
|
showFooter={true}
|