@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
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
today,
|
|
12
12
|
} from "@internationalized/date";
|
|
13
13
|
import { cn } from "../utils.js";
|
|
14
|
-
import { buttonVariants } from "
|
|
15
|
-
import { RangeCalendar } from "
|
|
16
|
-
import * as Popover from "
|
|
14
|
+
import { buttonVariants } from "./ui/button/index.js";
|
|
15
|
+
import { RangeCalendar } from "./ui/range-calendar/index.js";
|
|
16
|
+
import * as Popover from "./ui/popover/index.js";
|
|
17
17
|
import Input from "./ui/input/input.svelte";
|
|
18
18
|
|
|
19
19
|
interface Props {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { CircleSlash2, Zap } from "lucide-svelte";
|
|
3
|
-
import DataTable from "
|
|
4
|
-
import SidebarTrigger from "
|
|
3
|
+
import DataTable from "../../dataTable/dataTable.svelte";
|
|
4
|
+
import SidebarTrigger from "../../sidebar/sidebarTrigger.svelte";
|
|
5
5
|
import { getStudioContext } from "../../../context";
|
|
6
|
-
import Singletone from "
|
|
6
|
+
import Singletone from "../../singletone.svelte";
|
|
7
7
|
|
|
8
8
|
const { ctx } = getStudioContext();
|
|
9
9
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import type { SideBarData, SideBarNode } from "
|
|
3
|
-
import Sidebar from "
|
|
2
|
+
import type { SideBarData, SideBarNode } from "../../sidebar/sidebarElements.svelte";
|
|
3
|
+
import Sidebar from "../../sidebar/sidebar.svelte";
|
|
4
4
|
import { getStudioContext } from "../../../context";
|
|
5
5
|
import Collection from "./collection.svelte";
|
|
6
6
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { SvelteFlowProvider } from "@xyflow/svelte";
|
|
3
3
|
import Flow from "./flow.svelte";
|
|
4
|
-
import Sidebar from "
|
|
4
|
+
import Sidebar from "../../sidebar/sidebar.svelte";
|
|
5
5
|
import { location } from "@wjfe/n-savant";
|
|
6
6
|
import SyncManager from "./syncManager.svelte";
|
|
7
|
-
import SidebarTrigger from "
|
|
7
|
+
import SidebarTrigger from "../../sidebar/sidebarTrigger.svelte";
|
|
8
8
|
|
|
9
9
|
const currentPage = $derived(location.url.pathname.replace("/studio", "").split("/")[2]);
|
|
10
10
|
</script>
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import DiffViewer from "
|
|
2
|
+
import DiffViewer from "../../diffViewer.svelte";
|
|
3
3
|
import { getStudioContext } from "../../../context";
|
|
4
4
|
|
|
5
5
|
const { lobb, ctx } = getStudioContext();
|
|
6
6
|
import { onMount } from "svelte";
|
|
7
7
|
import stringify from "json-stable-stringify";
|
|
8
|
-
import CodeEditor from "
|
|
9
|
-
import Table from "
|
|
10
|
-
import Button from "
|
|
8
|
+
import CodeEditor from "../../codeEditor.svelte";
|
|
9
|
+
import Table from "../../dataTable/table.svelte";
|
|
10
|
+
import Button from "../../ui/button/button.svelte";
|
|
11
11
|
import { LoaderCircle, SendHorizontal } from "lucide-svelte";
|
|
12
12
|
|
|
13
13
|
let configSchema: string = $state("");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import ExtensionsComponents from "
|
|
2
|
+
import ExtensionsComponents from "../../extensionsComponents.svelte";
|
|
3
3
|
import { getExtensionUtils } from "../../../extensions/extensionUtils";
|
|
4
4
|
import { getStudioContext } from "../../../context";
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import Button from "
|
|
2
|
+
import Button from "../ui/button/button.svelte";
|
|
3
3
|
import { location } from "@wjfe/n-savant";
|
|
4
4
|
import { ArrowRight } from "lucide-svelte";
|
|
5
5
|
import HomeFooter from "./homeFooter.svelte";
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import type { SideBarData, SideBarNode } from "
|
|
2
|
+
import type { SideBarData, SideBarNode } from "../../sidebar/sidebarElements.svelte";
|
|
3
3
|
import WorkflowEditor, {
|
|
4
4
|
type WorkflowEntry,
|
|
5
|
-
} from "
|
|
5
|
+
} from "../../workflowEditor.svelte";
|
|
6
6
|
import { getStudioContext } from "../../../context";
|
|
7
7
|
|
|
8
8
|
const { lobb, ctx } = getStudioContext();
|
|
9
|
-
import Sidebar from "
|
|
10
|
-
import Button from "
|
|
9
|
+
import Sidebar from "../../sidebar/sidebar.svelte";
|
|
10
|
+
import Button from "../../ui/button/button.svelte";
|
|
11
11
|
import { location } from "@wjfe/n-savant";
|
|
12
12
|
import { CircleSlash2, Plus, Trash2 } from "lucide-svelte";
|
|
13
13
|
import { onMount } from "svelte";
|
|
14
14
|
import { showDialog } from "../../../actions";
|
|
15
|
-
import SidebarTrigger from "
|
|
15
|
+
import SidebarTrigger from "../../sidebar/sidebarTrigger.svelte";
|
|
16
16
|
|
|
17
17
|
let { workflowName } = $props();
|
|
18
18
|
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
import Button, { type ButtonProps } from "./ui/button/button.svelte";
|
|
4
4
|
import DataTable from "./dataTable/dataTable.svelte";
|
|
5
5
|
import { getCollectionPrimaryField } from "./dataTable/utils";
|
|
6
|
-
import { emitEvent } from "../eventSystem";
|
|
7
6
|
import { getStudioContext } from "../context";
|
|
8
7
|
import Drawer from "./drawer.svelte";
|
|
9
8
|
|
|
@@ -36,26 +35,8 @@
|
|
|
36
35
|
|
|
37
36
|
let openDrawer = $state(false);
|
|
38
37
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const eventResult = await emitEvent(
|
|
42
|
-
{ lobb, ctx },
|
|
43
|
-
"studio.collections.preForeignKeySelect",
|
|
44
|
-
{
|
|
45
|
-
parentCollectionName,
|
|
46
|
-
collectionName,
|
|
47
|
-
fieldName,
|
|
48
|
-
entry,
|
|
49
|
-
},
|
|
50
|
-
);
|
|
51
|
-
if (eventResult.filter) {
|
|
52
|
-
additionalFilter = eventResult.filter;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
openDrawer = true;
|
|
56
|
-
} catch (error) {
|
|
57
|
-
console.error(error);
|
|
58
|
-
}
|
|
38
|
+
function handleButtonClick() {
|
|
39
|
+
openDrawer = true;
|
|
59
40
|
}
|
|
60
41
|
|
|
61
42
|
async function onSelectHandler(entry: any) {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { toast } from "svelte-sonner";
|
|
3
3
|
import Button from "./ui/button/button.svelte";
|
|
4
4
|
import { getStudioContext } from "../context";
|
|
5
|
-
import { Input } from "
|
|
5
|
+
import { Input } from "./ui/input";
|
|
6
6
|
|
|
7
7
|
const { ctx } = getStudioContext();
|
|
8
8
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { RangeCalendar as RangeCalendarPrimitive } from "bits-ui";
|
|
3
|
-
import { buttonVariants } from "
|
|
3
|
+
import { buttonVariants } from "../button/index.js";
|
|
4
4
|
import { cn } from "../../../utils.js";
|
|
5
5
|
|
|
6
6
|
let {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { RangeCalendar as RangeCalendarPrimitive } from "bits-ui";
|
|
3
3
|
import ChevronRight from "@lucide/svelte/icons/chevron-right";
|
|
4
|
-
import { buttonVariants } from "
|
|
4
|
+
import { buttonVariants } from "../button/index.js";
|
|
5
5
|
import { cn } from "../../../utils.js";
|
|
6
6
|
let {
|
|
7
7
|
ref = $bindable(null),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { RangeCalendar as RangeCalendarPrimitive } from "bits-ui";
|
|
3
3
|
import ChevronLeft from "@lucide/svelte/icons/chevron-left";
|
|
4
|
-
import { buttonVariants } from "
|
|
4
|
+
import { buttonVariants } from "../button/index.js";
|
|
5
5
|
import { cn } from "../../../utils.js";
|
|
6
6
|
let {
|
|
7
7
|
ref = $bindable(null),
|
|
@@ -12,11 +12,11 @@
|
|
|
12
12
|
|
|
13
13
|
<script lang="ts">
|
|
14
14
|
import { getStudioContext } from "../context";
|
|
15
|
-
import CodeEditor from "
|
|
15
|
+
import CodeEditor from "./codeEditor.svelte";
|
|
16
16
|
|
|
17
17
|
const { lobb, ctx } = getStudioContext();
|
|
18
|
-
import Button from "
|
|
19
|
-
import Input from "
|
|
18
|
+
import Button from "./ui/button/button.svelte";
|
|
19
|
+
import Input from "./ui/input/input.svelte";
|
|
20
20
|
import { location } from "@wjfe/n-savant";
|
|
21
21
|
import { Edit, Plus } from "lucide-svelte";
|
|
22
22
|
import { toast } from "svelte-sonner";
|
package/dist/store.types.d.ts
CHANGED
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.29.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
@@ -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.2.0",
|
|
91
91
|
"@lucide/svelte": "^0.563.1",
|
|
92
92
|
"@tailwindcss/vite": "^4.3.0",
|
|
93
93
|
"@tiptap/core": "^3.0.0",
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { Toaster } from "
|
|
2
|
+
import { Toaster } from "./ui/sonner";
|
|
3
3
|
import { onMount, onDestroy } from "svelte";
|
|
4
4
|
import { ModeWatcher } from "mode-watcher";
|
|
5
5
|
import { createLobb } from "../store.svelte";
|
|
6
6
|
import { setStudioContext } from "../context";
|
|
7
|
-
import Header from "
|
|
7
|
+
import Header from "./header.svelte";
|
|
8
8
|
import { LoaderCircle, ServerOff } from "lucide-svelte";
|
|
9
|
-
import MiniSidebar from "
|
|
10
|
-
import * as Tooltip from "
|
|
9
|
+
import MiniSidebar from "./miniSidebar.svelte";
|
|
10
|
+
import * as Tooltip from "./ui/tooltip";
|
|
11
11
|
import { Router, Route, Fallback, init as initRouter } from "@wjfe/n-savant";
|
|
12
12
|
import {
|
|
13
13
|
executeExtensionsOnStartup,
|
|
@@ -45,6 +45,9 @@
|
|
|
45
45
|
let cleanupRouter: (() => void) | undefined;
|
|
46
46
|
|
|
47
47
|
onMount(async () => {
|
|
48
|
+
// Remove the static loading screen defined in app.html — it shows instantly
|
|
49
|
+
// before JS loads to avoid a blank page, and is replaced by the Studio UI.
|
|
50
|
+
document.getElementById("app-loading")?.remove();
|
|
48
51
|
cleanupRouter = initRouter();
|
|
49
52
|
try {
|
|
50
53
|
ctx.meta = await lobb.getMeta();
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
import CheckIcon from "@lucide/svelte/icons/check";
|
|
3
3
|
import ChevronsUpDownIcon from "@lucide/svelte/icons/chevrons-up-down";
|
|
4
4
|
import { tick } from "svelte";
|
|
5
|
-
import * as Command from "
|
|
6
|
-
import * as Popover from "
|
|
7
|
-
import { Button } from "
|
|
5
|
+
import * as Command from "./ui/command/index.js";
|
|
6
|
+
import * as Popover from "./ui/popover/index.js";
|
|
7
|
+
import { Button } from "./ui/button/index.js";
|
|
8
8
|
import { cn } from "../utils.js";
|
|
9
9
|
import type { HTMLButtonAttributes } from "svelte/elements";
|
|
10
10
|
|
|
@@ -4,12 +4,6 @@
|
|
|
4
4
|
recordId: string | number;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
export type RecordOperation =
|
|
8
|
-
| { type: "link"; record: any }
|
|
9
|
-
| { type: "unlink"; id: string | number }
|
|
10
|
-
| { type: "delete"; id: string | number }
|
|
11
|
-
| { type: "create"; record: any }
|
|
12
|
-
| { type: "update"; id: string | number; data: any };
|
|
13
7
|
</script>
|
|
14
8
|
|
|
15
9
|
<script lang="ts">
|
|
@@ -20,15 +14,14 @@
|
|
|
20
14
|
import Table, { type TableProps } from "./table.svelte";
|
|
21
15
|
import { getCollectionColumns, getCollectionParamsFields } from "./utils";
|
|
22
16
|
import { Pencil, Trash, Unlink } from "lucide-svelte";
|
|
23
|
-
import * as icons from "lucide-svelte";
|
|
24
17
|
import ListViewChildren from "./listViewChildren.svelte";
|
|
25
18
|
import FieldCell from "./fieldCell.svelte";
|
|
26
19
|
import Skeleton from "../ui/skeleton/skeleton.svelte";
|
|
27
20
|
import Button from "../ui/button/button.svelte";
|
|
28
21
|
import { showDialog } from "../../actions";
|
|
29
22
|
import UpdateDetailViewButton from "../detailView/update/updateDetailViewButton.svelte";
|
|
30
|
-
import { emitEvent } from "../../eventSystem";
|
|
31
23
|
import type { Snippet } from "svelte";
|
|
24
|
+
import type { Changes, ChildrenChanges } from "../detailView/utils";
|
|
32
25
|
import ExtensionsComponents from "../extensionsComponents.svelte";
|
|
33
26
|
import { getExtensionUtils, loadExtensionComponents } from "../../extensions/extensionUtils";
|
|
34
27
|
import Tabs from "./dataTableTabs.svelte";
|
|
@@ -41,7 +34,7 @@
|
|
|
41
34
|
filter?: any;
|
|
42
35
|
searchParams?: Record<string, any>;
|
|
43
36
|
parentContext?: ParentContext;
|
|
44
|
-
|
|
37
|
+
changes?: ChildrenChanges;
|
|
45
38
|
showHeader?: boolean;
|
|
46
39
|
showFooter?: boolean;
|
|
47
40
|
showImport?: boolean;
|
|
@@ -56,7 +49,7 @@
|
|
|
56
49
|
filter,
|
|
57
50
|
searchParams,
|
|
58
51
|
parentContext,
|
|
59
|
-
|
|
52
|
+
changes = $bindable<ChildrenChanges | undefined>(undefined),
|
|
60
53
|
showHeader = true,
|
|
61
54
|
showFooter = true,
|
|
62
55
|
showImport = true,
|
|
@@ -66,6 +59,46 @@
|
|
|
66
59
|
headerLeft,
|
|
67
60
|
}: Props = $props();
|
|
68
61
|
|
|
62
|
+
function getOrCreateUpdatedSlot(recordId: string): Changes | undefined {
|
|
63
|
+
if (!changes) return undefined;
|
|
64
|
+
let slot = changes.updated.find((u) => String(u.id) === String(recordId));
|
|
65
|
+
if (!slot) {
|
|
66
|
+
slot = { id: recordId, data: {}, children: {} };
|
|
67
|
+
changes.updated.push(slot);
|
|
68
|
+
}
|
|
69
|
+
return slot;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Derives the displayed rows by applying changes on top of server data.
|
|
73
|
+
// This is the single place responsible for optimistic UI — no handler touches data directly.
|
|
74
|
+
const data = $derived.by(() => {
|
|
75
|
+
if (!changes) return serverData;
|
|
76
|
+
|
|
77
|
+
const removedIds = new Set([
|
|
78
|
+
...changes.deleted.map((r) => String(r.id)),
|
|
79
|
+
...changes.unlinked.map((r) => String(r.id)),
|
|
80
|
+
]);
|
|
81
|
+
|
|
82
|
+
let result = serverData.filter((r: any) => !removedIds.has(String(r.id)));
|
|
83
|
+
|
|
84
|
+
result = result.map((r: any) => {
|
|
85
|
+
const update = changes.updated.find((u) => String(u.id) === String(r.id));
|
|
86
|
+
return update && Object.keys(update.data).length ? { ...r, ...update.data } : r;
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
for (const record of changes.linked) {
|
|
90
|
+
if (!result.some((r: any) => String(r.id) === String(record.id))) {
|
|
91
|
+
result = [...result, record];
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
for (const item of changes.created) {
|
|
96
|
+
result = [...result, { ...item.data, _pending: true }];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return result;
|
|
100
|
+
});
|
|
101
|
+
|
|
69
102
|
const hasRowActions = $derived(
|
|
70
103
|
loadExtensionComponents(ctx, "listView.entry.actions", undefined, { collectionName }).length > 0
|
|
71
104
|
);
|
|
@@ -89,7 +122,7 @@
|
|
|
89
122
|
|
|
90
123
|
let selectedRecords = $state([]);
|
|
91
124
|
let totalCount = $state(0);
|
|
92
|
-
let
|
|
125
|
+
let serverData: TableProps["data"] = $state([]);
|
|
93
126
|
let loading = $state(true);
|
|
94
127
|
const columns: TableProps["columns"] = $state(
|
|
95
128
|
getCollectionColumns(ctx, collectionName),
|
|
@@ -108,7 +141,6 @@
|
|
|
108
141
|
|
|
109
142
|
async function loadData(params: any) {
|
|
110
143
|
loading = true;
|
|
111
|
-
// parsing sort before sending the request
|
|
112
144
|
const paramsCopy = $state.snapshot(params);
|
|
113
145
|
const sort: TableProps["sort"] = paramsCopy.sort;
|
|
114
146
|
const sortStrings: string[] = [];
|
|
@@ -118,77 +150,43 @@
|
|
|
118
150
|
}
|
|
119
151
|
}
|
|
120
152
|
paramsCopy.sort = sortStrings.join(",");
|
|
121
|
-
|
|
122
|
-
// sending the request
|
|
123
153
|
const response = await lobb.findAll(collectionName, paramsCopy);
|
|
124
154
|
const res = await response.json();
|
|
125
|
-
|
|
126
|
-
data = res.data;
|
|
155
|
+
serverData = res.data;
|
|
127
156
|
totalCount = res.meta.totalCount;
|
|
128
|
-
|
|
129
157
|
loading = false;
|
|
130
158
|
}
|
|
131
159
|
|
|
132
|
-
// Internal handler: updates data optimistically then calls onOperation
|
|
133
|
-
function applyOperation(op: RecordOperation) {
|
|
134
|
-
if (op.type === "link") {
|
|
135
|
-
data = [...data, op.record];
|
|
136
|
-
} else if (op.type === "unlink" || op.type === "delete") {
|
|
137
|
-
data = data.filter((r: any) => String(r.id) !== String(op.id));
|
|
138
|
-
} else if (op.type === "create") {
|
|
139
|
-
data = [...data, { ...op.record, _pending: true }];
|
|
140
|
-
} else if (op.type === "update") {
|
|
141
|
-
data = data.map((r: any) => String(r.id) === String(op.id) ? { ...r, ...op.data } : r);
|
|
142
|
-
}
|
|
143
|
-
onOperation?.(op);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
160
|
async function handleDelete(entryId: string) {
|
|
147
161
|
const result = await showDialog("Are you sure?", "This will permanently delete the record.");
|
|
148
|
-
if (result)
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
162
|
+
if (!result) return;
|
|
163
|
+
if (changes) {
|
|
164
|
+
const record = data.find((r: any) => String(r.id) === String(entryId));
|
|
165
|
+
if (record) changes.deleted.push($state.snapshot(record));
|
|
166
|
+
} else if (parentContext) {
|
|
167
|
+
serverData = serverData.filter((r: any) => String(r.id) !== String(entryId));
|
|
168
|
+
await lobb.updateOne(parentContext.collectionName, String(parentContext.recordId), {}, { [collectionName]: { delete: [entryId] } });
|
|
169
|
+
params = { ...params };
|
|
170
|
+
} else {
|
|
171
|
+
serverData = serverData.filter((r: any) => String(r.id) !== String(entryId));
|
|
172
|
+
await lobb.deleteOne(collectionName, entryId);
|
|
173
|
+
params = { ...params };
|
|
158
174
|
}
|
|
159
175
|
}
|
|
160
176
|
|
|
161
177
|
async function handleUnlink(entryId: string) {
|
|
162
178
|
const result = await showDialog("Are you sure?", "This will unlink the record without deleting it.");
|
|
163
|
-
if (result)
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
}
|
|
179
|
+
if (!result) return;
|
|
180
|
+
if (changes) {
|
|
181
|
+
const record = data.find((r: any) => String(r.id) === String(entryId));
|
|
182
|
+
if (record) changes.unlinked.push($state.snapshot(record));
|
|
183
|
+
} else {
|
|
184
|
+
serverData = serverData.filter((r: any) => String(r.id) !== String(entryId));
|
|
185
|
+
await lobb.updateOne(parentContext!.collectionName, String(parentContext!.recordId), {}, { [collectionName]: { unlink: [entryId] } });
|
|
186
|
+
params = { ...params };
|
|
170
187
|
}
|
|
171
188
|
}
|
|
172
189
|
|
|
173
|
-
async function getWorkflowTools(
|
|
174
|
-
entry: Record<string, any>,
|
|
175
|
-
): Promise<any[]> {
|
|
176
|
-
// TODO: instead of firing the events like this. get them all the fire them one by one to get their results
|
|
177
|
-
const eventResult = await emitEvent(
|
|
178
|
-
{ lobb, ctx },
|
|
179
|
-
"studio.collections.listView.tools",
|
|
180
|
-
{
|
|
181
|
-
collectionName,
|
|
182
|
-
entry,
|
|
183
|
-
},
|
|
184
|
-
);
|
|
185
|
-
|
|
186
|
-
if (eventResult) {
|
|
187
|
-
return eventResult.tools;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
return [];
|
|
191
|
-
}
|
|
192
190
|
</script>
|
|
193
191
|
|
|
194
192
|
<div
|
|
@@ -209,7 +207,14 @@
|
|
|
209
207
|
{/snippet}
|
|
210
208
|
|
|
211
209
|
{#if showHeader}
|
|
212
|
-
<Header
|
|
210
|
+
<Header
|
|
211
|
+
bind:params
|
|
212
|
+
{collectionName}
|
|
213
|
+
bind:selectedRecords
|
|
214
|
+
{showImport}
|
|
215
|
+
{parentContext}
|
|
216
|
+
{changes}
|
|
217
|
+
>
|
|
213
218
|
{#snippet left()}
|
|
214
219
|
{@render headerLeft?.()}
|
|
215
220
|
{/snippet}
|
|
@@ -246,6 +251,7 @@
|
|
|
246
251
|
variant="ghost"
|
|
247
252
|
class="h-5 w-5 px-0 py-0 text-muted-foreground hover:bg-transparent"
|
|
248
253
|
Icon={Pencil}
|
|
254
|
+
changes={getOrCreateUpdatedSlot(String(entry.id))}
|
|
249
255
|
onSuccessfullSave={async () => {
|
|
250
256
|
params = { ...params };
|
|
251
257
|
}}
|
|
@@ -270,20 +276,6 @@
|
|
|
270
276
|
title="Delete permanently"
|
|
271
277
|
></Button>
|
|
272
278
|
{/if}
|
|
273
|
-
{#await getWorkflowTools($state.snapshot(entry))}
|
|
274
|
-
<div></div>
|
|
275
|
-
{:then workflowTools}
|
|
276
|
-
{#each workflowTools as workflowTool}
|
|
277
|
-
<Button
|
|
278
|
-
variant="ghost"
|
|
279
|
-
class="h-5 w-5 px-0 py-0 text-muted-foreground hover:bg-transparent"
|
|
280
|
-
Icon={icons[
|
|
281
|
-
workflowTool.icon as keyof typeof icons
|
|
282
|
-
]}
|
|
283
|
-
onclick={workflowTool.onclick}
|
|
284
|
-
></Button>
|
|
285
|
-
{/each}
|
|
286
|
-
{/await}
|
|
287
279
|
{/snippet}
|
|
288
280
|
{#snippet overrideCell(value, column, entry)}
|
|
289
281
|
<FieldCell
|
|
@@ -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";
|