@firecms/collection_editor 3.0.0-canary.136 → 3.0.0-canary.137

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/index.es.js CHANGED
@@ -3,7 +3,7 @@ import { FieldCaption, SearchIconsView, toSnakeCase, singular, IconForView, Arra
3
3
  import * as React from "react";
4
4
  import React__default, { useContext, useState, useEffect, useMemo, useRef, useDeferredValue, useCallback } from "react";
5
5
  import equal from "react-fast-compare";
6
- import { useAutoComplete, Container, Typography, Tooltip, IconButton, Chip, TextField, cls, DebouncedTextField, Autocomplete, AutocompleteItem, ExpandablePanel, SettingsIcon, ClearIcon, Select, SelectItem, BooleanSwitchWithLabel, Dialog, AutoAwesomeIcon, Badge, ListIcon, Button, CircularProgress, Paper, DialogContent, DialogActions, RuleIcon, FileUploadIcon, MultiSelect, MultiSelectItem, cardMixin, cardClickableMixin, cardSelectedMixin, FunctionsIcon, RemoveCircleIcon, defaultBorderMixin, RemoveIcon, DragHandleIcon, AddIcon, SelectGroup, InfoLabel, DeleteIcon, ContentCopyIcon, CodeIcon, Table, TableBody, TableRow, TableCell, Alert, Icon, Card, coolIconKeys, Tabs, Tab, ArrowBackIcon, LoadingButton, DoneIcon, Menu, MoreVertIcon, MenuItem, SaveIcon, UndoIcon } from "@firecms/ui";
6
+ import { useAutoComplete, Container, Typography, Tooltip, IconButton, Chip, TextField, cls, DebouncedTextField, Autocomplete, AutocompleteItem, ExpandablePanel, SettingsIcon, ClearIcon, Select, SelectItem, BooleanSwitchWithLabel, Dialog, AutoAwesomeIcon, Badge, ListIcon, Button, CircularProgress, Paper, DialogContent, DialogActions, RuleIcon, FileUploadIcon, MultiSelect, MultiSelectItem, cardMixin, cardClickableMixin, cardSelectedMixin, FunctionsIcon, RemoveCircleIcon, defaultBorderMixin, RemoveIcon, DragHandleIcon, AddIcon, SelectGroup, InfoLabel, DeleteIcon, fieldBackgroundMixin, fieldBackgroundDisabledMixin, fieldBackgroundHoverMixin, DialogTitle, Card, WarningOffIcon, ContentCopyIcon, CodeIcon, Table, TableBody, TableRow, TableCell, Alert, Icon, coolIconKeys, Tabs, Tab, ArrowBackIcon, LoadingButton, DoneIcon, Menu, MoreVertIcon, MenuItem, SaveIcon, UndoIcon } from "@firecms/ui";
7
7
  import * as Yup from "yup";
8
8
  import { useFormex, Field, getIn, useCreateFormex, Formex } from "@firecms/formex";
9
9
  import { extractEnumFromValues, buildPropertyFromData, buildEntityPropertiesFromData } from "@firecms/schema_inference";
@@ -2796,40 +2796,6 @@ function updatePropertyFromWidget(propertyData, selectedWidgetId, propertyConfig
2796
2796
  }
2797
2797
  return updatedProperty;
2798
2798
  }
2799
- function PropertySelectItem({ value, optionDisabled, propertyConfig, existing }) {
2800
- return /* @__PURE__ */ jsx(
2801
- SelectItem,
2802
- {
2803
- value,
2804
- disabled: optionDisabled,
2805
- className: "flex flex-row items-center",
2806
- children: /* @__PURE__ */ jsxs(
2807
- "div",
2808
- {
2809
- className: cls(
2810
- "flex flex-row items-center text-base min-h-[48px]",
2811
- optionDisabled ? "w-full" : ""
2812
- ),
2813
- children: [
2814
- /* @__PURE__ */ jsx("div", { className: "mr-8", children: /* @__PURE__ */ jsx(PropertyConfigBadge, { propertyConfig }) }),
2815
- /* @__PURE__ */ jsxs("div", { children: [
2816
- /* @__PURE__ */ jsx("div", { children: propertyConfig.name }),
2817
- /* @__PURE__ */ jsx(
2818
- Typography,
2819
- {
2820
- variant: "caption",
2821
- color: "disabled",
2822
- className: "max-w-sm",
2823
- children: existing && optionDisabled ? "You can only switch to widgets that use the same data type" : propertyConfig.description
2824
- }
2825
- )
2826
- ] })
2827
- ]
2828
- }
2829
- )
2830
- }
2831
- );
2832
- }
2833
2799
  function UrlPropertyField({
2834
2800
  disabled,
2835
2801
  showErrors
@@ -3046,6 +3012,7 @@ const PropertyForm = React__default.memo(
3046
3012
  property,
3047
3013
  onPropertyChanged,
3048
3014
  onPropertyChangedImmediate = true,
3015
+ onDismiss,
3049
3016
  onDelete,
3050
3017
  onError,
3051
3018
  initialErrors,
@@ -3152,6 +3119,7 @@ const PropertyForm = React__default.memo(
3152
3119
  includeIdAndTitle: includeIdAndName,
3153
3120
  propertyNamespace,
3154
3121
  onError,
3122
+ onDismiss,
3155
3123
  showErrors: forceShowErrors || formexController.submitCount > 0,
3156
3124
  existing: existingProperty,
3157
3125
  autoUpdateId,
@@ -3202,6 +3170,7 @@ function PropertyFormDialog({
3202
3170
  PropertyForm,
3203
3171
  {
3204
3172
  ...formProps,
3173
+ onDismiss: onCancel,
3205
3174
  onPropertyChanged: (params) => {
3206
3175
  onPropertyChanged?.(params);
3207
3176
  onOkClicked?.();
@@ -3251,6 +3220,7 @@ function PropertyEditFormFields({
3251
3220
  onPropertyChanged,
3252
3221
  onDelete,
3253
3222
  propertyNamespace,
3223
+ onDismiss,
3254
3224
  onError,
3255
3225
  showErrors,
3256
3226
  disabled,
@@ -3263,8 +3233,6 @@ function PropertyEditFormFields({
3263
3233
  const [selectOpen, setSelectOpen] = useState(autoOpenTypeSelect);
3264
3234
  const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
3265
3235
  const [selectedFieldConfigId, setSelectedFieldConfigId] = useState(values?.dataType ? getFieldId(values) : void 0);
3266
- const allSupportedFields = Object.entries(supportedFields).concat(Object.entries(propertyConfigs));
3267
- const displayedWidgets = inArray ? allSupportedFields.filter(([_, propertyConfig]) => !isPropertyBuilder(propertyConfig.property) && propertyConfig.property?.dataType !== "array") : allSupportedFields;
3268
3236
  const deferredValues = useDeferredValue(values);
3269
3237
  const nameFieldRef = useRef(null);
3270
3238
  const lastSubmittedProperty = useRef(values);
@@ -3445,72 +3413,23 @@ function PropertyEditFormFields({
3445
3413
  /* @__PURE__ */ jsxs("div", { className: "flex mt-2 justify-between", children: [
3446
3414
  /* @__PURE__ */ jsxs("div", { className: "w-full flex flex-col gap-2", children: [
3447
3415
  /* @__PURE__ */ jsx(
3448
- Select,
3416
+ WidgetSelectView,
3449
3417
  {
3450
- error: Boolean(selectedWidgetError),
3451
- value: selectedFieldConfigId ?? "",
3452
- placeholder: "Select a property widget",
3418
+ initialProperty: values,
3419
+ value: selectedFieldConfigId,
3420
+ onValueChange: (value) => onWidgetSelectChanged(value),
3453
3421
  open: selectOpen,
3454
- onOpenChange: setSelectOpen,
3455
- position: "item-aligned",
3456
- disabled,
3457
- renderValue: (value) => {
3458
- if (!value) {
3459
- return /* @__PURE__ */ jsx("em", { children: "Select a property widget" });
3422
+ onOpenChange: (open, hasValue) => {
3423
+ if (!hasValue) {
3424
+ onDismiss?.();
3460
3425
  }
3461
- const key = value;
3462
- const propertyConfig = DEFAULT_FIELD_CONFIGS[key] ?? propertyConfigs[key];
3463
- const baseProperty = propertyConfig.property;
3464
- const baseFieldConfig = baseProperty && !isPropertyBuilder(baseProperty) ? getFieldConfig(baseProperty, propertyConfigs) : void 0;
3465
- const optionDisabled = isPropertyBuilder(baseProperty) || existing && baseProperty.dataType !== values?.dataType;
3466
- const computedFieldConfig = baseFieldConfig ? mergeDeep(baseFieldConfig, propertyConfig) : propertyConfig;
3467
- return /* @__PURE__ */ jsxs(
3468
- "div",
3469
- {
3470
- onClick: (e) => {
3471
- if (optionDisabled) {
3472
- e.stopPropagation();
3473
- e.preventDefault();
3474
- }
3475
- },
3476
- className: cls(
3477
- "flex items-center",
3478
- optionDisabled ? "w-full pointer-events-none opacity-50" : ""
3479
- ),
3480
- children: [
3481
- /* @__PURE__ */ jsx("div", { className: "mr-8", children: /* @__PURE__ */ jsx(PropertyConfigBadge, { propertyConfig: computedFieldConfig }) }),
3482
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-start text-base text-left", children: [
3483
- /* @__PURE__ */ jsx("div", { children: computedFieldConfig.name }),
3484
- /* @__PURE__ */ jsx(
3485
- Typography,
3486
- {
3487
- variant: "caption",
3488
- color: "disabled",
3489
- children: optionDisabled ? "You can only switch to widgets that use the same data type" : computedFieldConfig.description
3490
- }
3491
- )
3492
- ] })
3493
- ]
3494
- }
3495
- );
3496
- },
3497
- onValueChange: (value) => {
3498
- onWidgetSelectChanged(value);
3426
+ setSelectOpen(open);
3499
3427
  },
3500
- children: displayedWidgets.map(([key, propertyConfig]) => {
3501
- const baseProperty = propertyConfig.property;
3502
- const optionDisabled = existing && !isPropertyBuilder(baseProperty) && baseProperty.dataType !== values?.dataType;
3503
- return /* @__PURE__ */ jsx(
3504
- PropertySelectItem,
3505
- {
3506
- value: key,
3507
- optionDisabled,
3508
- propertyConfig,
3509
- existing
3510
- },
3511
- key
3512
- );
3513
- })
3428
+ disabled,
3429
+ showError: Boolean(selectedWidgetError),
3430
+ existing,
3431
+ propertyConfigs,
3432
+ inArray
3514
3433
  }
3515
3434
  ),
3516
3435
  selectedWidgetError && /* @__PURE__ */ jsx(
@@ -3586,6 +3505,196 @@ function validateName(value) {
3586
3505
  }
3587
3506
  return error;
3588
3507
  }
3508
+ const WIDGET_TYPE_MAP = {
3509
+ text_field: "Text",
3510
+ multiline: "Text",
3511
+ markdown: "Text",
3512
+ url: "Text",
3513
+ email: "Text",
3514
+ switch: "Boolean",
3515
+ select: "Select",
3516
+ multi_select: "Select",
3517
+ number_input: "Number",
3518
+ number_select: "Select",
3519
+ multi_number_select: "Select",
3520
+ file_upload: "File",
3521
+ multi_file_upload: "File",
3522
+ reference: "Reference",
3523
+ multi_references: "Reference",
3524
+ date_time: "Date",
3525
+ group: "Group",
3526
+ key_value: "Group",
3527
+ repeat: "Array",
3528
+ custom_array: "Array",
3529
+ block: "Group"
3530
+ };
3531
+ function WidgetSelectView({
3532
+ initialProperty,
3533
+ value,
3534
+ onValueChange,
3535
+ open,
3536
+ onOpenChange,
3537
+ disabled,
3538
+ showError,
3539
+ existing,
3540
+ propertyConfigs,
3541
+ inArray
3542
+ }) {
3543
+ const allSupportedFields = Object.entries(supportedFields).concat(Object.entries(propertyConfigs));
3544
+ const displayedWidgets = (inArray ? allSupportedFields.filter(([_, propertyConfig2]) => !isPropertyBuilder(propertyConfig2.property) && propertyConfig2.property?.dataType !== "array") : allSupportedFields).map(([key2, propertyConfig2]) => ({
3545
+ [key2]: propertyConfig2
3546
+ })).reduce((a, b) => {
3547
+ return {
3548
+ ...a,
3549
+ ...b
3550
+ };
3551
+ }, {});
3552
+ const key = value;
3553
+ const propertyConfig = key ? DEFAULT_FIELD_CONFIGS[key] ?? propertyConfigs[key] : void 0;
3554
+ const baseProperty = propertyConfig?.property;
3555
+ const baseFieldConfig = baseProperty && !isPropertyBuilder(baseProperty) ? getFieldConfig(baseProperty, propertyConfigs) : void 0;
3556
+ const computedFieldConfig = baseFieldConfig && propertyConfig ? mergeDeep(baseFieldConfig, propertyConfig) : propertyConfig;
3557
+ const groups = [...new Set(Object.keys(displayedWidgets).map((key2) => {
3558
+ const group = WIDGET_TYPE_MAP[key2];
3559
+ if (group) {
3560
+ return group;
3561
+ }
3562
+ return "Custom/Other";
3563
+ }))];
3564
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
3565
+ /* @__PURE__ */ jsxs(
3566
+ "div",
3567
+ {
3568
+ onClick: () => {
3569
+ if (!disabled) {
3570
+ onOpenChange(!open, Boolean(value));
3571
+ }
3572
+ },
3573
+ className: cls(
3574
+ "select-none rounded-md text-sm p-4",
3575
+ fieldBackgroundMixin,
3576
+ disabled ? fieldBackgroundDisabledMixin : fieldBackgroundHoverMixin,
3577
+ "relative flex items-center"
3578
+ ),
3579
+ children: [
3580
+ !value && /* @__PURE__ */ jsx("em", { children: "Select a property widget" }),
3581
+ value && computedFieldConfig && /* @__PURE__ */ jsxs(
3582
+ "div",
3583
+ {
3584
+ className: cls(
3585
+ "flex items-center"
3586
+ ),
3587
+ children: [
3588
+ /* @__PURE__ */ jsx("div", { className: "mr-8", children: /* @__PURE__ */ jsx(PropertyConfigBadge, { propertyConfig: computedFieldConfig }) }),
3589
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-start text-base text-left", children: [
3590
+ /* @__PURE__ */ jsx("div", { children: computedFieldConfig.name }),
3591
+ /* @__PURE__ */ jsx(
3592
+ Typography,
3593
+ {
3594
+ variant: "caption",
3595
+ color: "secondary",
3596
+ children: computedFieldConfig.description
3597
+ }
3598
+ )
3599
+ ] })
3600
+ ]
3601
+ }
3602
+ )
3603
+ ]
3604
+ }
3605
+ ),
3606
+ /* @__PURE__ */ jsxs(
3607
+ Dialog,
3608
+ {
3609
+ open,
3610
+ onOpenChange: (open2) => onOpenChange(open2, Boolean(value)),
3611
+ maxWidth: "4xl",
3612
+ children: [
3613
+ /* @__PURE__ */ jsx(DialogTitle, { children: "Select a property widget" }),
3614
+ /* @__PURE__ */ jsx(DialogContent, { children: /* @__PURE__ */ jsx("div", { children: groups.map((group) => {
3615
+ return /* @__PURE__ */ jsxs("div", { className: "mt-4", children: [
3616
+ /* @__PURE__ */ jsx(Typography, { variant: "label", children: group }),
3617
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-x-4 gap-y-2 mt-4", children: Object.entries(displayedWidgets).map(([key2, propertyConfig2]) => {
3618
+ const groupKey = WIDGET_TYPE_MAP[key2];
3619
+ if (groupKey === group) {
3620
+ return /* @__PURE__ */ jsx(
3621
+ WidgetSelectViewItem,
3622
+ {
3623
+ initialProperty,
3624
+ onClick: () => {
3625
+ onValueChange(key2);
3626
+ onOpenChange(false, true);
3627
+ },
3628
+ propertyConfig: propertyConfig2,
3629
+ existing
3630
+ },
3631
+ key2
3632
+ );
3633
+ }
3634
+ return null;
3635
+ }) })
3636
+ ] }, group);
3637
+ }) }) })
3638
+ ]
3639
+ }
3640
+ )
3641
+ ] });
3642
+ }
3643
+ function WidgetSelectViewItem({
3644
+ onClick,
3645
+ initialProperty,
3646
+ // optionDisabled,
3647
+ propertyConfig,
3648
+ existing
3649
+ }) {
3650
+ const baseProperty = propertyConfig.property;
3651
+ const shouldWarnChangingDataType = existing && !isPropertyBuilder(baseProperty) && baseProperty.dataType !== initialProperty?.dataType;
3652
+ return /* @__PURE__ */ jsx(
3653
+ Card,
3654
+ {
3655
+ onClick,
3656
+ className: "flex flex-row items-center px-4 py-2",
3657
+ children: /* @__PURE__ */ jsxs(
3658
+ "div",
3659
+ {
3660
+ className: cls(
3661
+ "flex flex-row items-center text-base min-h-[48px]"
3662
+ ),
3663
+ children: [
3664
+ /* @__PURE__ */ jsx("div", { className: "mr-8", children: /* @__PURE__ */ jsx(PropertyConfigBadge, { propertyConfig, disabled: shouldWarnChangingDataType }) }),
3665
+ /* @__PURE__ */ jsxs("div", { children: [
3666
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-row gap-2 items-center", children: [
3667
+ shouldWarnChangingDataType && /* @__PURE__ */ jsx(
3668
+ Tooltip,
3669
+ {
3670
+ title: "This widget uses a different data type than the initially selected widget. This can cause errors with existing data.",
3671
+ children: /* @__PURE__ */ jsx(WarningOffIcon, { size: "smallest", className: "w-4" })
3672
+ }
3673
+ ),
3674
+ /* @__PURE__ */ jsx(
3675
+ Typography,
3676
+ {
3677
+ color: shouldWarnChangingDataType ? "secondary" : void 0,
3678
+ children: propertyConfig.name
3679
+ }
3680
+ )
3681
+ ] }),
3682
+ /* @__PURE__ */ jsx(
3683
+ Typography,
3684
+ {
3685
+ variant: "caption",
3686
+ color: "secondary",
3687
+ className: "max-w-sm",
3688
+ children: propertyConfig.description
3689
+ }
3690
+ )
3691
+ ] })
3692
+ ]
3693
+ }
3694
+ )
3695
+ }
3696
+ );
3697
+ }
3589
3698
  function camelCase(str) {
3590
3699
  if (!str) return "";
3591
3700
  return (str.slice(0, 1).toLowerCase() + str.slice(1)).replace(/([-_ ]){1,}/g, " ").split(/[-_ ]/).reduce((cur, acc) => {
@@ -4078,6 +4187,7 @@ function CollectionPropertiesEditorForm({
4078
4187
  getData,
4079
4188
  propertyConfigs,
4080
4189
  collectionEditable,
4190
+ onCancel: closePropertyDialog,
4081
4191
  onOkClicked: asDialog ? closePropertyDialog : void 0
4082
4192
  },
4083
4193
  `edit_view_${selectedPropertyIndex}`
@@ -5218,6 +5328,40 @@ function PropertySelect({
5218
5328
  }
5219
5329
  );
5220
5330
  }
5331
+ function PropertySelectItem({ value, optionDisabled, propertyConfig, existing }) {
5332
+ return /* @__PURE__ */ jsx(
5333
+ SelectItem,
5334
+ {
5335
+ value,
5336
+ disabled: optionDisabled,
5337
+ className: "flex flex-row items-center",
5338
+ children: /* @__PURE__ */ jsxs(
5339
+ "div",
5340
+ {
5341
+ className: cls(
5342
+ "flex flex-row items-center text-base min-h-[48px]",
5343
+ optionDisabled ? "w-full" : ""
5344
+ ),
5345
+ children: [
5346
+ /* @__PURE__ */ jsx("div", { className: "mr-8", children: /* @__PURE__ */ jsx(PropertyConfigBadge, { propertyConfig }) }),
5347
+ /* @__PURE__ */ jsxs("div", { children: [
5348
+ /* @__PURE__ */ jsx("div", { children: propertyConfig.name }),
5349
+ /* @__PURE__ */ jsx(
5350
+ Typography,
5351
+ {
5352
+ variant: "caption",
5353
+ color: "disabled",
5354
+ className: "max-w-sm",
5355
+ children: existing && optionDisabled ? "You can only switch to widgets that use the same data type" : propertyConfig.description
5356
+ }
5357
+ )
5358
+ ] })
5359
+ ]
5360
+ }
5361
+ )
5362
+ }
5363
+ );
5364
+ }
5221
5365
  function CollectionEditorImportDataPreview({
5222
5366
  importConfig,
5223
5367
  properties,