@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
|
@@ -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>
|
|
@@ -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
|
>
|
|
@@ -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();
|
|
@@ -108,7 +112,7 @@
|
|
|
108
112
|
>
|
|
109
113
|
<div
|
|
110
114
|
class="
|
|
111
|
-
flex items-center justify-between px-2 h-10 bg-muted
|
|
115
|
+
flex items-center justify-between px-2 h-10 bg-muted-soft
|
|
112
116
|
{expanded ? 'border-b' : ''}
|
|
113
117
|
"
|
|
114
118
|
>
|
|
@@ -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}
|
|
@@ -161,13 +165,12 @@
|
|
|
161
165
|
</div>
|
|
162
166
|
</div>
|
|
163
167
|
{#if expanded}
|
|
164
|
-
<div bind:clientWidth={tableWidth} class="bg-muted
|
|
168
|
+
<div bind:clientWidth={tableWidth} class="bg-muted-soft overflow-auto">
|
|
165
169
|
<Table
|
|
166
170
|
data={entries}
|
|
167
171
|
{columns}
|
|
168
172
|
selectByColumn="id"
|
|
169
173
|
showCollapsible={doesCollectionHasChildren}
|
|
170
|
-
unifiedBgColor="bg-muted/30"
|
|
171
174
|
>
|
|
172
175
|
{#snippet tools(entry, index)}
|
|
173
176
|
<Button
|
|
@@ -197,7 +200,7 @@
|
|
|
197
200
|
class="h-6 w-6 text-muted-foreground hover:bg-transparent p-0"
|
|
198
201
|
Icon={Pencil}
|
|
199
202
|
{collectionName}
|
|
200
|
-
|
|
203
|
+
changes={editChanges}
|
|
201
204
|
showRelatedRecords={true}
|
|
202
205
|
onSuccessfullSave={(entry) =>
|
|
203
206
|
onRecordOverride(entry, index)}
|
|
@@ -236,7 +239,6 @@
|
|
|
236
239
|
{collectionName}
|
|
237
240
|
recordId={entry.id}
|
|
238
241
|
width={tableWidth}
|
|
239
|
-
unifiedBgColor="bg-muted/30"
|
|
240
242
|
/>
|
|
241
243
|
{:else}
|
|
242
244
|
<SubRecords
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { CircleHelp } from "lucide-svelte";
|
|
3
|
+
import * as Tooltip from "../ui/tooltip";
|
|
4
|
+
import { getStudioContext } from "../../context";
|
|
5
|
+
import ExtensionsComponents from "../extensionsComponents.svelte";
|
|
6
|
+
import { getExtensionUtils } from "../../extensions/extensionUtils";
|
|
7
|
+
import { getField, getFieldIcon } from "../dataTable/utils";
|
|
8
|
+
import FieldInput from "./fieldInput.svelte";
|
|
9
|
+
|
|
10
|
+
interface Props {
|
|
11
|
+
collectionName: string;
|
|
12
|
+
entry: Record<string, any>;
|
|
13
|
+
fieldsErrors?: Record<string, string[]>;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let {
|
|
17
|
+
collectionName,
|
|
18
|
+
entry = $bindable(),
|
|
19
|
+
fieldsErrors = {},
|
|
20
|
+
}: Props = $props();
|
|
21
|
+
|
|
22
|
+
const { lobb, ctx } = getStudioContext();
|
|
23
|
+
const fieldNames = $derived(
|
|
24
|
+
Object.keys(ctx.meta.collections[collectionName].fields),
|
|
25
|
+
);
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<div class="flex flex-col gap-4 p-4">
|
|
29
|
+
{#each fieldNames as fieldName}
|
|
30
|
+
{#if !ctx.meta.collections[collectionName].fields[fieldName]?.ui?.hidden}
|
|
31
|
+
{@const field = getField(ctx, fieldName, collectionName)}
|
|
32
|
+
{@const FieldIcon = getFieldIcon(ctx, fieldName, collectionName)}
|
|
33
|
+
{@const description = ctx.meta.collections[collectionName].fields[fieldName]?.description}
|
|
34
|
+
<div class="flex flex-col gap-2">
|
|
35
|
+
<div class="flex flex-1 items-end justify-between gap-2 text-xs">
|
|
36
|
+
<div class="flex items-center gap-1.5">
|
|
37
|
+
<ExtensionsComponents
|
|
38
|
+
name="detailView.field.label"
|
|
39
|
+
utils={getExtensionUtils(lobb, ctx)}
|
|
40
|
+
{collectionName}
|
|
41
|
+
{fieldName}
|
|
42
|
+
bind:value={entry[fieldName]}
|
|
43
|
+
>
|
|
44
|
+
<div class="flex items-center gap-1.5">
|
|
45
|
+
<div class="h-fit">{field.label}</div>
|
|
46
|
+
<div class="flex h-fit items-center gap-1 text-[0.7rem] text-muted-foreground">
|
|
47
|
+
<FieldIcon size="12" />
|
|
48
|
+
{field.type}
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
</ExtensionsComponents>
|
|
52
|
+
{#if description}
|
|
53
|
+
<Tooltip.Root>
|
|
54
|
+
<Tooltip.Trigger>
|
|
55
|
+
<CircleHelp size="12" class="text-muted-foreground" />
|
|
56
|
+
</Tooltip.Trigger>
|
|
57
|
+
<Tooltip.Content class="max-w-64 text-xs">
|
|
58
|
+
{description}
|
|
59
|
+
</Tooltip.Content>
|
|
60
|
+
</Tooltip.Root>
|
|
61
|
+
{/if}
|
|
62
|
+
</div>
|
|
63
|
+
<div>
|
|
64
|
+
<ExtensionsComponents
|
|
65
|
+
name="dvFields.topRight.{collectionName}.{fieldName}"
|
|
66
|
+
utils={getExtensionUtils(lobb, ctx)}
|
|
67
|
+
bind:value={entry[fieldName]}
|
|
68
|
+
/>
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
<FieldInput
|
|
72
|
+
{collectionName}
|
|
73
|
+
{fieldName}
|
|
74
|
+
bind:value={entry[fieldName]}
|
|
75
|
+
bind:entry
|
|
76
|
+
errorMessages={fieldsErrors[fieldName]}
|
|
77
|
+
/>
|
|
78
|
+
</div>
|
|
79
|
+
{/if}
|
|
80
|
+
{/each}
|
|
81
|
+
</div>
|
|
@@ -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";
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
{:else if field.label === "id"}
|
|
87
87
|
<Input
|
|
88
88
|
placeholder="AUTO GENERATED"
|
|
89
|
-
class="bg-muted
|
|
89
|
+
class="bg-muted-soft text-xs"
|
|
90
90
|
bind:value
|
|
91
91
|
/>
|
|
92
92
|
{:else if fieldRelationTarget && entry}
|
|
@@ -126,7 +126,7 @@
|
|
|
126
126
|
>
|
|
127
127
|
<Select.Trigger
|
|
128
128
|
class="
|
|
129
|
-
h-9 w-full bg-muted
|
|
129
|
+
h-9 w-full bg-muted-soft pr-8
|
|
130
130
|
{destructive ? 'border-destructive bg-destructive/10' : ''}
|
|
131
131
|
"
|
|
132
132
|
>
|
|
@@ -158,7 +158,7 @@
|
|
|
158
158
|
placeholder={ui?.placeholder ? ui.placeholder : "NULL"}
|
|
159
159
|
type="text"
|
|
160
160
|
class="
|
|
161
|
-
bg-muted
|
|
161
|
+
bg-muted-soft text-xs
|
|
162
162
|
{destructive ? 'border-destructive bg-destructive/10' : ''}
|
|
163
163
|
"
|
|
164
164
|
bind:value
|
|
@@ -168,7 +168,7 @@
|
|
|
168
168
|
placeholder={ui?.placeholder ? ui.placeholder : value === "" ? "EMPTY STRING" : "NULL"}
|
|
169
169
|
rows={5}
|
|
170
170
|
class="
|
|
171
|
-
bg-muted
|
|
171
|
+
bg-muted-soft text-xs
|
|
172
172
|
{destructive ? 'border-destructive bg-destructive/10' : ''}
|
|
173
173
|
"
|
|
174
174
|
bind:value
|
|
@@ -178,7 +178,7 @@
|
|
|
178
178
|
type="date"
|
|
179
179
|
placeholder={ui?.placeholder ? ui.placeholder : "NULL"}
|
|
180
180
|
class="
|
|
181
|
-
dateInput block w-full bg-muted
|
|
181
|
+
dateInput block w-full bg-muted-soft pr-9 text-xs
|
|
182
182
|
{destructive ? 'border-destructive bg-destructive/10' : ''}
|
|
183
183
|
"
|
|
184
184
|
bind:value={
|
|
@@ -197,7 +197,7 @@
|
|
|
197
197
|
type="time"
|
|
198
198
|
placeholder={ui?.placeholder ? ui.placeholder : "NULL"}
|
|
199
199
|
class="
|
|
200
|
-
dateInput block w-full bg-muted
|
|
200
|
+
dateInput block w-full bg-muted-soft pr-9 text-xs
|
|
201
201
|
{destructive ? 'border-destructive bg-destructive/10' : ''}
|
|
202
202
|
"
|
|
203
203
|
bind:value={
|
|
@@ -215,7 +215,7 @@
|
|
|
215
215
|
type="datetime-local"
|
|
216
216
|
placeholder={ui?.placeholder ? ui.placeholder : "NULL"}
|
|
217
217
|
class="
|
|
218
|
-
dateInput block w-full bg-muted
|
|
218
|
+
dateInput block w-full bg-muted-soft pr-9 text-xs
|
|
219
219
|
{destructive ? 'border-destructive bg-destructive/10' : ''}
|
|
220
220
|
"
|
|
221
221
|
bind:value={
|
|
@@ -236,7 +236,7 @@
|
|
|
236
236
|
<Select.Trigger
|
|
237
237
|
placeholder={ui?.placeholder ? ui.placeholder : "NULL"}
|
|
238
238
|
class="
|
|
239
|
-
bg-muted
|
|
239
|
+
bg-muted-soft pr-9
|
|
240
240
|
{destructive ? 'border-destructive bg-destructive/10' : ''}
|
|
241
241
|
"
|
|
242
242
|
>
|
|
@@ -263,7 +263,7 @@
|
|
|
263
263
|
type="number"
|
|
264
264
|
step="any"
|
|
265
265
|
class="
|
|
266
|
-
bg-muted
|
|
266
|
+
bg-muted-soft text-xs
|
|
267
267
|
{destructive ? 'border-destructive bg-destructive/10' : ''}
|
|
268
268
|
"
|
|
269
269
|
bind:value
|
|
@@ -273,7 +273,7 @@
|
|
|
273
273
|
placeholder={ui?.placeholder ? ui.placeholder : "NULL"}
|
|
274
274
|
type="number"
|
|
275
275
|
class="
|
|
276
|
-
bg-muted
|
|
276
|
+
bg-muted-soft text-xs
|
|
277
277
|
{destructive ? 'border-destructive bg-destructive/10' : ''}
|
|
278
278
|
"
|
|
279
279
|
bind:value
|
|
@@ -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";
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
placeholder={field.placeholder ? field.placeholder : "NULL"}
|
|
50
50
|
type="text"
|
|
51
51
|
class="
|
|
52
|
-
bg-muted
|
|
52
|
+
bg-muted-soft text-xs
|
|
53
53
|
{destructive ? 'border-destructive bg-destructive/10' : ''}
|
|
54
54
|
"
|
|
55
55
|
bind:value
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
<Select.Trigger
|
|
65
65
|
placeholder={field.placeholder ? field.placeholder : "NULL"}
|
|
66
66
|
class="
|
|
67
|
-
h-9 w-full bg-muted
|
|
67
|
+
h-9 w-full bg-muted-soft pr-8
|
|
68
68
|
{destructive ? 'border-destructive bg-destructive/10' : ''}
|
|
69
69
|
"
|
|
70
70
|
>
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
placeholder={field.placeholder ? field.placeholder : value === "" ? "EMPTY STRING" : "NULL"}
|
|
85
85
|
rows={5}
|
|
86
86
|
class="
|
|
87
|
-
bg-muted
|
|
87
|
+
bg-muted-soft text-xs
|
|
88
88
|
{destructive ? 'border-destructive bg-destructive/10' : ''}
|
|
89
89
|
"
|
|
90
90
|
bind:value
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
<Input
|
|
99
99
|
type="date"
|
|
100
100
|
class="
|
|
101
|
-
dateInput block w-full bg-muted
|
|
101
|
+
dateInput block w-full bg-muted-soft pr-9 text-xs
|
|
102
102
|
{destructive ? 'border-destructive bg-destructive/10' : ''}
|
|
103
103
|
"
|
|
104
104
|
bind:value={
|
|
@@ -116,7 +116,7 @@
|
|
|
116
116
|
<Input
|
|
117
117
|
type="time"
|
|
118
118
|
class="
|
|
119
|
-
dateInput block w-full bg-muted
|
|
119
|
+
dateInput block w-full bg-muted-soft pr-9 text-xs
|
|
120
120
|
{destructive ? 'border-destructive bg-destructive/10' : ''}
|
|
121
121
|
"
|
|
122
122
|
bind:value={
|
|
@@ -133,7 +133,7 @@
|
|
|
133
133
|
<Input
|
|
134
134
|
type="datetime-local"
|
|
135
135
|
class="
|
|
136
|
-
dateInput block w-full bg-muted
|
|
136
|
+
dateInput block w-full bg-muted-soft pr-9 text-xs
|
|
137
137
|
{destructive ? 'border-destructive bg-destructive/10' : ''}
|
|
138
138
|
"
|
|
139
139
|
bind:value={
|
|
@@ -154,7 +154,7 @@
|
|
|
154
154
|
<Select.Root type="single" bind:value>
|
|
155
155
|
<Select.Trigger
|
|
156
156
|
class="
|
|
157
|
-
bg-muted
|
|
157
|
+
bg-muted-soft pr-9
|
|
158
158
|
{destructive ? 'border-destructive bg-destructive/10' : ''}
|
|
159
159
|
"
|
|
160
160
|
>
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
<Input
|
|
22
22
|
type="password"
|
|
23
23
|
placeholder="••••••"
|
|
24
|
-
class="bg-muted
|
|
24
|
+
class="bg-muted-soft text-xs {destructive ? 'border-destructive bg-destructive/10' : ''}"
|
|
25
25
|
value={displayValue}
|
|
26
26
|
oninput={onInput}
|
|
27
27
|
/>
|