@rebasepro/admin 0.2.1 → 0.2.3

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.
Files changed (35) hide show
  1. package/dist/{CollectionEditorDialog-BXIh2AXg.js → CollectionEditorDialog-CmGXXSY9.js} +6 -182
  2. package/dist/CollectionEditorDialog-CmGXXSY9.js.map +1 -0
  3. package/dist/{CollectionsStudioView-jR8iz_ja.js → CollectionsStudioView-DcLHT5bU.js} +4 -4
  4. package/dist/{CollectionsStudioView-jR8iz_ja.js.map → CollectionsStudioView-DcLHT5bU.js.map} +1 -1
  5. package/dist/{ContentHomePage-BQZWuOFb.js → ContentHomePage-C7vFqKSe.js} +2 -2
  6. package/dist/{ContentHomePage-BQZWuOFb.js.map → ContentHomePage-C7vFqKSe.js.map} +1 -1
  7. package/dist/{ExportCollectionAction-CMdiiv1L.js → ExportCollectionAction-BfN34eWX.js} +2 -2
  8. package/dist/{ExportCollectionAction-CMdiiv1L.js.map → ExportCollectionAction-BfN34eWX.js.map} +1 -1
  9. package/dist/{ImportCollectionAction-C05lE0IW.js → ImportCollectionAction-SZrInjhx.js} +2 -2
  10. package/dist/{ImportCollectionAction-C05lE0IW.js.map → ImportCollectionAction-SZrInjhx.js.map} +1 -1
  11. package/dist/{PropertyEditView-BB5xjnhZ.js → PropertyEditView-Cvryrb3B.js} +304 -326
  12. package/dist/PropertyEditView-Cvryrb3B.js.map +1 -0
  13. package/dist/{RolesView-CULIHWZ9.js → RolesView-BCb7qwWs.js} +2 -2
  14. package/dist/{RolesView-CULIHWZ9.js.map → RolesView-BCb7qwWs.js.map} +1 -1
  15. package/dist/{UsersView-D7_AtJ44.js → UsersView-Cex24r8H.js} +2 -2
  16. package/dist/{UsersView-D7_AtJ44.js.map → UsersView-Cex24r8H.js.map} +1 -1
  17. package/dist/collection_editor/ui/collection_editor/properties/RelationPropertyField.d.ts +1 -7
  18. package/dist/collection_editor_ui.js +3 -3
  19. package/dist/{index-D5OQhv-T.js → index-DjduZG1T.js} +3 -3
  20. package/dist/index-DjduZG1T.js.map +1 -0
  21. package/dist/{index-CoSNm3e3.js → index-MKPc70-v.js} +3 -3
  22. package/dist/index-MKPc70-v.js.map +1 -0
  23. package/dist/{index-BAM9KCmM.js → index-PLIQXpTt.js} +2 -2
  24. package/dist/{index-BAM9KCmM.js.map → index-PLIQXpTt.js.map} +1 -1
  25. package/dist/index.js +4 -4
  26. package/dist/{util-DtbWD7LF.js → util-DbWax_sV.js} +95 -15
  27. package/dist/{util-DtbWD7LF.js.map → util-DbWax_sV.js.map} +1 -1
  28. package/package.json +10 -9
  29. package/src/collection_editor/ui/collection_editor/CollectionEditorDialog.tsx +1 -10
  30. package/src/collection_editor/ui/collection_editor/properties/RelationPropertyField.tsx +37 -57
  31. package/src/collection_editor/validateCollectionJson.ts +88 -1
  32. package/dist/CollectionEditorDialog-BXIh2AXg.js.map +0 -1
  33. package/dist/PropertyEditView-BB5xjnhZ.js.map +0 -1
  34. package/dist/index-CoSNm3e3.js.map +0 -1
  35. package/dist/index-D5OQhv-T.js.map +0 -1
@@ -1,10 +1,10 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
2
  import { c } from "react-compiler-runtime";
3
3
  import { useAuthController, useCustomizationController, IconForView, useSnackbarController, useLargeLayout, AIIcon, useRebaseContext, ErrorView, ConfirmationDialog, useUnsavedChangesDialog, UnsavedChangesDialog } from "@rebasepro/core";
4
- import { bi as useCollectionsConfigController, J as FieldCaption, ad as SearchIconsView, aL as getFieldConfig, $ as PropertyConfigBadge, aN as getFullId, aV as idToPropertiesPath, aZ as namespaceToPropertiesOrderPath, bu as validateCollectionJson, bh as useCollectionRegistryController, C as CollectionGenerationApiError, bg as useCollectionEditorController, O as ImportFileUpload, aR as getInferenceType, P as ImportNewPropertyFieldPreview, p as DataNewPropertiesMapping, aM as getFieldId, bp as useSelectionController, ay as convertDataToEntity, w as EntityCollectionTable, bm as useNavigationStateController, bk as useImportConfig, bt as useUrlController, Q as ImportSaveInProgress, aO as getFullIdPath } from "./util-DtbWD7LF.js";
4
+ import { bi as useCollectionsConfigController, J as FieldCaption, ad as SearchIconsView, aL as getFieldConfig, $ as PropertyConfigBadge, aN as getFullId, aV as idToPropertiesPath, aZ as namespaceToPropertiesOrderPath, bu as validateCollectionJson, bh as useCollectionRegistryController, C as CollectionGenerationApiError, bg as useCollectionEditorController, O as ImportFileUpload, aR as getInferenceType, P as ImportNewPropertyFieldPreview, p as DataNewPropertiesMapping, aM as getFieldId, bp as useSelectionController, ay as convertDataToEntity, w as EntityCollectionTable, bm as useNavigationStateController, bk as useImportConfig, bt as useUrlController, Q as ImportSaveInProgress, aO as getFullIdPath } from "./util-DbWax_sV.js";
5
5
  import * as React from "react";
6
6
  import React__default, { useState, useRef, useMemo, useEffect } from "react";
7
- import { Chip, Typography, cls, Tooltip, IconButton, TextField, DebouncedTextField, Dialog, Container, ColumnsIcon, SquareIcon, PanelLeftIcon, AppWindow, ToggleButtonGroup, ListIcon, TableIcon, LayoutGridIcon, KanbanIcon, Select, SelectItem, XIcon, iconSize, Button, BooleanSwitchWithLabel, DialogTitle, DialogContent, CopyIcon, DialogActions, CircularProgress, FileSearchIcon, PlusIcon, ErrorBoundary, defaultBorderMixin, Table, TableHeader, TableCell, TableBody, TableRow, Trash2Icon, CodeIcon, Alert, Menu, ShoppingCartIcon, UserIcon, FileTextIcon, FileIcon, Card, CircularProgressCenter, Paper, KeyIcon, MultiSelect, MultiSelectItem, coolIconKeys, Tabs, Tab, LoadingButton, ArrowLeftIcon, CheckIcon } from "@rebasepro/ui";
7
+ import { Chip, Typography, cls, Tooltip, IconButton, TextField, DebouncedTextField, Dialog, Container, ColumnsIcon, SquareIcon, PanelLeftIcon, AppWindow, ToggleButtonGroup, ListIcon, TableIcon, LayoutGridIcon, KanbanIcon, Select, SelectItem, XIcon, iconSize, Button, BooleanSwitchWithLabel, DialogTitle, DialogContent, CopyIcon, DialogActions, CircularProgress, FileSearchIcon, PlusIcon, ErrorBoundary, defaultBorderMixin, CodeIcon, Alert, Menu, ShoppingCartIcon, UserIcon, FileTextIcon, FileIcon, Card, CircularProgressCenter, Paper, KeyIcon, Trash2Icon, MultiSelect, MultiSelectItem, coolIconKeys, Tabs, Tab, LoadingButton, ArrowLeftIcon, CheckIcon } from "@rebasepro/ui";
8
8
  import { isPropertyBuilder, getSubcollections, getTableName, removeInitialAndTrailingSlashes } from "@rebasepro/common";
9
9
  import "fast-equals";
10
10
  import { useFormex, getIn, Field, clone, useCreateFormex, Formex } from "@rebasepro/formex";
@@ -21,7 +21,7 @@ import "exceljs";
21
21
  import { buildPropertyFromData, buildEntityPropertiesFromData } from "@rebasepro/schema-inference";
22
22
  import "date-fns";
23
23
  import "date-fns/locale";
24
- import { b as PropertyFormDialog, d as useAIModifiedPaths, c as PropertyTree, a as PropertyForm, s as supportedFields, u as updatePropertyFromWidget, A as AIModifiedPathsProvider } from "./PropertyEditView-BB5xjnhZ.js";
24
+ import { b as PropertyFormDialog, d as useAIModifiedPaths, c as PropertyTree, a as PropertyForm, s as supportedFields, u as updatePropertyFromWidget, A as AIModifiedPathsProvider } from "./PropertyEditView-Cvryrb3B.js";
25
25
  import JSON5 from "json5";
26
26
  import { Highlight, themes } from "prism-react-renderer";
27
27
  const CollectionEditorSchema = z.object({
@@ -1391,180 +1391,6 @@ function CollectionPropertiesEditorForm({
1391
1391
  /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(GetCodeDialog, { collection: values, open: codeDialogOpen, onOpenChange: setCodeDialogOpen }) })
1392
1392
  ] });
1393
1393
  }
1394
- function CollectionRelationsTab() {
1395
- const {
1396
- values,
1397
- setFieldValue
1398
- } = useFormex();
1399
- const {
1400
- collections
1401
- } = useCollectionsConfigController();
1402
- const [editingRelationIndex, setEditingRelationIndex] = useState(null);
1403
- const [editingRelationState, setEditingRelationState] = useState(null);
1404
- const getTargetSlug = (target) => {
1405
- if (typeof target === "string") {
1406
- const match = target.match(/\(\)\s*=>\s*([a-zA-Z0-9_]+)/);
1407
- return match ? match[1] : target;
1408
- }
1409
- if (typeof target === "function") {
1410
- try {
1411
- if (target.slug) return target.slug;
1412
- const col = target();
1413
- return col?.slug || col?.name || "";
1414
- } catch (e) {
1415
- return "";
1416
- }
1417
- }
1418
- return "";
1419
- };
1420
- const relations = values.relations || [];
1421
- const handleDelete = (index) => {
1422
- const newRelations = [...relations];
1423
- newRelations.splice(index, 1);
1424
- setFieldValue("relations", newRelations);
1425
- };
1426
- const handleSave = () => {
1427
- if (!editingRelationState) return;
1428
- const newRelations_0 = [...relations];
1429
- if (editingRelationIndex === -1) {
1430
- newRelations_0.push(editingRelationState);
1431
- } else if (editingRelationIndex !== null) {
1432
- newRelations_0[editingRelationIndex] = editingRelationState;
1433
- }
1434
- setFieldValue("relations", newRelations_0);
1435
- setEditingRelationIndex(null);
1436
- setEditingRelationState(null);
1437
- };
1438
- const handleCancel = () => {
1439
- setEditingRelationIndex(null);
1440
- setEditingRelationState(null);
1441
- };
1442
- return /* @__PURE__ */ jsx("div", { className: "overflow-auto my-auto h-full w-full", children: /* @__PURE__ */ jsxs(Container, { maxWidth: "4xl", className: "flex flex-col gap-4 p-8 m-auto h-full", children: [
1443
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-8", children: [
1444
- /* @__PURE__ */ jsx(Typography, { variant: "h5", children: "Relations" }),
1445
- /* @__PURE__ */ jsx(Button, { variant: "filled", color: "neutral", onClick: () => {
1446
- setEditingRelationIndex(-1);
1447
- setEditingRelationState({
1448
- relationName: "",
1449
- target: "",
1450
- cardinality: "many",
1451
- direction: "owning"
1452
- });
1453
- }, children: "ADD RELATION" })
1454
- ] }),
1455
- relations.length > 0 ? /* @__PURE__ */ jsx("div", { className: "w-full overflow-auto border dark:border-surface-800 rounded-lg", children: /* @__PURE__ */ jsxs(Table, { className: "w-full", children: [
1456
- /* @__PURE__ */ jsxs(TableHeader, { children: [
1457
- /* @__PURE__ */ jsx(TableCell, { header: true, className: "w-16" }),
1458
- /* @__PURE__ */ jsx(TableCell, { header: true, children: "Name" }),
1459
- /* @__PURE__ */ jsx(TableCell, { header: true, children: "Target" }),
1460
- /* @__PURE__ */ jsx(TableCell, { header: true, children: "Cardinality" }),
1461
- /* @__PURE__ */ jsx(TableCell, { header: true, children: "Direction" })
1462
- ] }),
1463
- /* @__PURE__ */ jsx(TableBody, { children: relations.map((relation, index_0) => /* @__PURE__ */ jsxs(TableRow, { className: "cursor-pointer hover:bg-surface-100 dark:hover:bg-surface-800", onClick: () => {
1464
- setEditingRelationIndex(index_0);
1465
- setEditingRelationState(relation);
1466
- }, children: [
1467
- /* @__PURE__ */ jsx(TableCell, { style: {
1468
- width: "64px"
1469
- }, children: /* @__PURE__ */ jsx(IconButton, { size: "small", onClick: (e_0) => {
1470
- e_0.stopPropagation();
1471
- handleDelete(index_0);
1472
- }, children: /* @__PURE__ */ jsx(Trash2Icon, {}) }) }),
1473
- /* @__PURE__ */ jsx(TableCell, { className: "font-medium", children: relation.relationName }),
1474
- /* @__PURE__ */ jsx(TableCell, { children: getTargetSlug(relation.target) || "Function" }),
1475
- /* @__PURE__ */ jsx(TableCell, { children: relation.cardinality }),
1476
- /* @__PURE__ */ jsx(TableCell, { children: relation.direction || "owning" })
1477
- ] }, index_0)) })
1478
- ] }) }) : /* @__PURE__ */ jsxs("div", { className: "flex-grow flex flex-col border border-dashed dark:border-surface-700 rounded-lg items-center justify-center text-text-disabled py-20", children: [
1479
- /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "mb-4", children: "No relations defined for this collection." }),
1480
- /* @__PURE__ */ jsx(Button, { variant: "text", onClick: () => {
1481
- setEditingRelationIndex(-1);
1482
- setEditingRelationState({
1483
- relationName: "",
1484
- target: "",
1485
- cardinality: "many",
1486
- direction: "owning"
1487
- });
1488
- }, children: "Create your first relation" })
1489
- ] }),
1490
- /* @__PURE__ */ jsx(Dialog, { open: !!editingRelationState, onOpenChange: (open) => !open && handleCancel(), maxWidth: "2xl", children: editingRelationState && /* @__PURE__ */ jsxs(Fragment, { children: [
1491
- /* @__PURE__ */ jsx(DialogTitle, { className: "flex justify-between items-center w-full", variant: "h6", children: editingRelationIndex === -1 ? "New Relation" : "Edit Relation" }),
1492
- /* @__PURE__ */ jsx(DialogContent, { includeMargin: false, className: cls("p-4 md:p-6 border-t bg-white dark:bg-surface-900", defaultBorderMixin), children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 max-w-2xl mx-auto", children: [
1493
- /* @__PURE__ */ jsx(TextField, { label: "Relation Name", name: "relationName", placeholder: "e.g. posts", value: editingRelationState.relationName || "", onChange: (e_1) => setEditingRelationState((prev) => prev ? {
1494
- ...prev,
1495
- relationName: e_1.target.value
1496
- } : null) }),
1497
- /* @__PURE__ */ jsx(Select, { fullWidth: true, label: "Target Collection", value: getTargetSlug(editingRelationState.target), onValueChange: (val) => {
1498
- setEditingRelationState((prev_0) => {
1499
- if (!prev_0) return null;
1500
- const targetFn = () => collections?.find((c2) => c2.slug === val) || {
1501
- slug: val
1502
- };
1503
- targetFn.slug = val;
1504
- return {
1505
- ...prev_0,
1506
- target: targetFn
1507
- };
1508
- });
1509
- }, children: collections?.map((col_0) => /* @__PURE__ */ jsx(SelectItem, { value: col_0.slug, children: col_0.name || col_0.slug }, col_0.slug)) }),
1510
- /* @__PURE__ */ jsxs(Select, { fullWidth: true, label: "Cardinality", value: editingRelationState.cardinality || "many", onValueChange: (val_0) => setEditingRelationState((prev_1) => prev_1 ? {
1511
- ...prev_1,
1512
- cardinality: val_0
1513
- } : null), children: [
1514
- /* @__PURE__ */ jsx(SelectItem, { value: "many", children: "Many" }),
1515
- /* @__PURE__ */ jsx(SelectItem, { value: "one", children: "One" })
1516
- ] }),
1517
- /* @__PURE__ */ jsxs(Select, { fullWidth: true, label: "Direction", value: editingRelationState.direction || "owning", onValueChange: (val_1) => setEditingRelationState((prev_2) => prev_2 ? {
1518
- ...prev_2,
1519
- direction: val_1
1520
- } : null), children: [
1521
- /* @__PURE__ */ jsx(SelectItem, { value: "owning", children: "Owning" }),
1522
- /* @__PURE__ */ jsx(SelectItem, { value: "inverse", children: "Inverse" })
1523
- ] }),
1524
- editingRelationState.cardinality === "many" && editingRelationState.direction === "owning" && /* @__PURE__ */ jsxs("div", { className: cls("flex flex-col gap-4 mt-4 pt-4 border-t", defaultBorderMixin), children: [
1525
- /* @__PURE__ */ jsx(Typography, { variant: "subtitle2", className: "text-text-primary", children: "Intermediate Table" }),
1526
- /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-text-secondary -mt-3", children: "Required for many-to-many relationships. This defines the junction table linking both collections." }),
1527
- /* @__PURE__ */ jsx(TextField, { label: "Table Name", name: "throughTable", placeholder: "e.g. user_roles", value: editingRelationState.through?.table || "", onChange: (e_2) => setEditingRelationState((prev_3) => prev_3 ? {
1528
- ...prev_3,
1529
- through: {
1530
- ...prev_3.through || {
1531
- sourceColumn: "",
1532
- targetColumn: ""
1533
- },
1534
- table: e_2.target.value
1535
- }
1536
- } : null) }),
1537
- /* @__PURE__ */ jsxs("div", { className: "flex gap-4", children: [
1538
- /* @__PURE__ */ jsx(TextField, { className: "flex-1", label: "Source Column", name: "sourceColumn", placeholder: "FK to this collection", value: editingRelationState.through?.sourceColumn || "", onChange: (e_3) => setEditingRelationState((prev_4) => prev_4 ? {
1539
- ...prev_4,
1540
- through: {
1541
- ...prev_4.through || {
1542
- table: "",
1543
- targetColumn: ""
1544
- },
1545
- sourceColumn: e_3.target.value
1546
- }
1547
- } : null) }),
1548
- /* @__PURE__ */ jsx(TextField, { className: "flex-1", label: "Target Column", name: "targetColumn", placeholder: "FK to target collection", value: editingRelationState.through?.targetColumn || "", onChange: (e_4) => setEditingRelationState((prev_5) => prev_5 ? {
1549
- ...prev_5,
1550
- through: {
1551
- ...prev_5.through || {
1552
- table: "",
1553
- sourceColumn: ""
1554
- },
1555
- targetColumn: e_4.target.value
1556
- }
1557
- } : null) })
1558
- ] })
1559
- ] })
1560
- ] }) }),
1561
- /* @__PURE__ */ jsxs(DialogActions, { children: [
1562
- /* @__PURE__ */ jsx(Button, { variant: "text", onClick: handleCancel, children: "Cancel" }),
1563
- /* @__PURE__ */ jsx(Button, { variant: "filled", color: "primary", onClick: handleSave, disabled: !editingRelationState.relationName || !editingRelationState.target, children: "Save" })
1564
- ] })
1565
- ] }) })
1566
- ] }) });
1567
- }
1568
1394
  const EXAMPLE_JSON = `{
1569
1395
  "id": "products",
1570
1396
  "name": "Products",
@@ -4460,7 +4286,7 @@ function CollectionEditorInternal({
4460
4286
  };
4461
4287
  const validation = (col) => {
4462
4288
  let errors = {};
4463
- const schema = (currentView === "properties" || currentView === "relations" || currentView === "general") && CollectionEditorSchema;
4289
+ const schema = (currentView === "properties" || currentView === "general") && CollectionEditorSchema;
4464
4290
  if (schema) {
4465
4291
  const result = schema.safeParse(col);
4466
4292
  if (!result.success) {
@@ -4582,8 +4408,7 @@ function CollectionEditorInternal({
4582
4408
  /* @__PURE__ */ jsx(Tab, { value: "general", children: "General" }),
4583
4409
  /* @__PURE__ */ jsx(Tab, { value: "display", children: "Display" }),
4584
4410
  /* @__PURE__ */ jsx(Tab, { value: "properties", children: "Properties" }),
4585
- getDataSourceCapabilities(values_1.driver).supportsRLS && /* @__PURE__ */ jsx(Tab, { value: "rls", children: "RLS" }),
4586
- getDataSourceCapabilities(values_1.driver).supportsRelations && /* @__PURE__ */ jsx(Tab, { value: "relations", children: "Relations" })
4411
+ getDataSourceCapabilities(values_1.driver).supportsRLS && /* @__PURE__ */ jsx(Tab, { value: "rls", children: "RLS" })
4587
4412
  ] }) }),
4588
4413
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4", children: [
4589
4414
  generateCollection && /* @__PURE__ */ jsx(AICollectionGeneratorPopover, { existingCollection: values_1, onGenerated: handleAIGenerated, generateCollection, onAnalyticsEvent }),
@@ -4624,7 +4449,6 @@ function CollectionEditorInternal({
4624
4449
  } }),
4625
4450
  currentView === "general" && /* @__PURE__ */ jsx(GeneralSettingsForm, { existingPaths, existingIds, parentCollection, isNewCollection }),
4626
4451
  currentView === "display" && /* @__PURE__ */ jsx(DisplaySettingsForm, { expandKanban }),
4627
- currentView === "relations" && getDataSourceCapabilities(values_1.driver).supportsRelations && /* @__PURE__ */ jsx(CollectionRelationsTab, {}),
4628
4452
  currentView === "rls" && getDataSourceCapabilities(values_1.driver).supportsRLS && /* @__PURE__ */ jsx(CollectionRLSTab, {}),
4629
4453
  currentView === "properties" && /* @__PURE__ */ jsx(CollectionPropertiesEditorForm, { showErrors: submitCount > 0, isNewCollection, onPropertyError: (propertyKey, namespace, error_0) => {
4630
4454
  const current = removeUndefined({
@@ -4737,4 +4561,4 @@ export {
4737
4561
  CollectionEditor,
4738
4562
  CollectionEditorDialog
4739
4563
  };
4740
- //# sourceMappingURL=CollectionEditorDialog-BXIh2AXg.js.map
4564
+ //# sourceMappingURL=CollectionEditorDialog-CmGXXSY9.js.map