@firecms/core 3.1.0-canary.1df3b2c → 3.1.0-canary.9e89e98

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.
@@ -326,6 +326,14 @@ export interface EntityCollection<M extends Record<string, any> = any, USER exte
326
326
  * Defaults to "table".
327
327
  */
328
328
  defaultViewMode?: ViewMode;
329
+ /**
330
+ * Which view modes are available for this collection.
331
+ * Possible values: "table", "cards", "kanban".
332
+ * Defaults to all three: ["table", "cards", "kanban"].
333
+ * Note: "kanban" will only be available if the collection has at least
334
+ * one string property with enumValues defined, regardless of this setting.
335
+ */
336
+ enabledViews?: ViewMode[];
329
337
  /**
330
338
  * Configuration for Kanban board view mode.
331
339
  * When set, the Kanban view mode becomes available.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@firecms/core",
3
3
  "type": "module",
4
- "version": "3.1.0-canary.1df3b2c",
4
+ "version": "3.1.0-canary.9e89e98",
5
5
  "description": "Awesome Firebase/Firestore-based headless open-source CMS",
6
6
  "funding": {
7
7
  "url": "https://github.com/sponsors/firecmsco"
@@ -53,9 +53,9 @@
53
53
  "@dnd-kit/core": "^6.3.1",
54
54
  "@dnd-kit/modifiers": "^9.0.0",
55
55
  "@dnd-kit/sortable": "^10.0.0",
56
- "@firecms/editor": "^3.1.0-canary.1df3b2c",
57
- "@firecms/formex": "^3.1.0-canary.1df3b2c",
58
- "@firecms/ui": "^3.1.0-canary.1df3b2c",
56
+ "@firecms/editor": "^3.1.0-canary.9e89e98",
57
+ "@firecms/formex": "^3.1.0-canary.9e89e98",
58
+ "@firecms/ui": "^3.1.0-canary.9e89e98",
59
59
  "@radix-ui/react-portal": "^1.1.10",
60
60
  "clsx": "^2.1.1",
61
61
  "compressorjs": "^1.2.1",
@@ -111,7 +111,7 @@
111
111
  "dist",
112
112
  "src"
113
113
  ],
114
- "gitHead": "5074584b15be0d0507a4dadc148f03d82e9fe495",
114
+ "gitHead": "7631fbfb6cde4415513e45c0557e18073ab359b8",
115
115
  "publishConfig": {
116
116
  "access": "public"
117
117
  },
@@ -501,18 +501,24 @@ export const EntityCollectionView = React.memo(
501
501
  authController,
502
502
  }), [collection, fullPath]);
503
503
 
504
- // Check if Kanban view is available (needs kanban.columnProperty with enumValues)
505
- const kanbanEnabled = useMemo(() => {
506
- if (!collection.kanban?.columnProperty) return false;
507
- const property = getPropertyInPath(resolvedCollection.properties, collection.kanban.columnProperty);
508
- if (!property || !("dataType" in property) || property.dataType !== "string") return false;
509
- return Boolean(property.enumValues);
510
- }, [collection.kanban?.columnProperty, resolvedCollection.properties]);
511
-
512
- // Check if a plugin can configure Kanban (has KanbanSetupComponent)
513
- const hasKanbanConfigPlugin = useMemo(() => {
514
- return customizationController.plugins?.some(plugin => plugin.collectionView?.KanbanSetupComponent) ?? false;
515
- }, [customizationController.plugins]);
504
+ // Check if Kanban view is possible (collection has at least one string enum property)
505
+ const hasEnumProperty = useMemo(() => {
506
+ const properties = resolvedCollection.properties;
507
+ return Object.values(properties).some((prop: any) =>
508
+ prop && prop.dataType === "string" && prop.enumValues
509
+ );
510
+ }, [resolvedCollection.properties]);
511
+
512
+ // Compute the effective enabled views:
513
+ // - Start from collection.enabledViews (defaults to all three)
514
+ // - Filter out kanban if no enum properties exist
515
+ const enabledViews: ViewMode[] = useMemo(() => {
516
+ const configured = collection.enabledViews ?? ["table", "cards", "kanban"];
517
+ if (!hasEnumProperty) {
518
+ return configured.filter(v => v !== "kanban");
519
+ }
520
+ return configured;
521
+ }, [collection.enabledViews, hasEnumProperty]);
516
522
 
517
523
  // Compute available enum properties for kanban column selection
518
524
  const kanbanPropertyOptions: KanbanPropertyOption[] = useMemo(() => {
@@ -819,8 +825,7 @@ export const EntityCollectionView = React.memo(
819
825
  <ViewModeToggle
820
826
  viewMode={viewMode}
821
827
  onViewModeChange={onViewModeChange}
822
- kanbanEnabled={kanbanEnabled}
823
- hasKanbanConfigPlugin={hasKanbanConfigPlugin}
828
+ enabledViews={enabledViews}
824
829
  size={viewMode === "table" ? tableSize : viewMode === "cards" ? cardSize : undefined}
825
830
  onSizeChanged={viewMode === "table" ? onTableSizeChanged : viewMode === "cards" ? setCardSize : undefined}
826
831
  open={viewModePopoverOpen}
@@ -867,7 +872,7 @@ export const EntityCollectionView = React.memo(
867
872
  />
868
873
 
869
874
  {/* View content - only the view-specific content changes */}
870
- {viewMode === "kanban" && (kanbanEnabled || hasKanbanConfigPlugin) ? (
875
+ {viewMode === "kanban" && enabledViews.includes("kanban") ? (
871
876
  <EntityCollectionBoardView
872
877
  key={`kanban-view-${fullPath}-${selectedKanbanProperty}`}
873
878
  collection={collection}
@@ -22,16 +22,11 @@ export type ViewModeToggleProps = {
22
22
  viewMode?: ViewMode;
23
23
  onViewModeChange?: (mode: ViewMode) => void;
24
24
  /**
25
- * Whether Kanban view mode is available for this collection.
26
- * Should be true when collection.kanban is set with a valid enum property.
25
+ * Which view modes are enabled for this collection.
26
+ * Only these modes will appear in the toggle.
27
+ * Defaults to all three: ["table", "cards", "kanban"].
27
28
  */
28
- kanbanEnabled?: boolean;
29
- /**
30
- * Whether a plugin exists that can configure Kanban (e.g., collection editor).
31
- * When true, Kanban option is always shown (enabled or not based on kanbanEnabled).
32
- * When false, Kanban option is shown but disabled.
33
- */
34
- hasKanbanConfigPlugin?: boolean;
29
+ enabledViews?: ViewMode[];
35
30
  /**
36
31
  * Current size for card/table views
37
32
  */
@@ -62,11 +57,12 @@ export type ViewModeToggleProps = {
62
57
  onKanbanPropertyChange?: (property: string) => void;
63
58
  }
64
59
 
60
+ const ALL_VIEW_MODES: ViewMode[] = ["table", "cards", "kanban"];
61
+
65
62
  export function ViewModeToggle({
66
63
  viewMode = "table",
67
64
  onViewModeChange,
68
- kanbanEnabled = false,
69
- hasKanbanConfigPlugin = false,
65
+ enabledViews = ALL_VIEW_MODES,
70
66
  size,
71
67
  onSizeChanged,
72
68
  open,
@@ -93,16 +89,15 @@ export function ViewModeToggle({
93
89
  return "List";
94
90
  };
95
91
 
96
- const showKanban = kanbanEnabled || hasKanbanConfigPlugin;
97
92
  const showSizeSelector = size && onSizeChanged && (viewMode === "table" || viewMode === "cards");
98
93
  const showKanbanPropertySelector = viewMode === "kanban" &&
99
94
  kanbanPropertyOptions &&
100
95
  kanbanPropertyOptions.length > 0 &&
101
96
  onKanbanPropertyChange;
102
97
 
103
- // Build toggle options dynamically based on kanban availability
98
+ // Build toggle options based on enabledViews
104
99
  const viewModeOptions: ToggleButtonOption<ViewMode>[] = useMemo(() => {
105
- const options: ToggleButtonOption<ViewMode>[] = [
100
+ const allOptions: ToggleButtonOption<ViewMode>[] = [
106
101
  {
107
102
  value: "table",
108
103
  label: "List",
@@ -112,20 +107,21 @@ export function ViewModeToggle({
112
107
  value: "cards",
113
108
  label: "Cards",
114
109
  icon: <AppsIcon size="small" />
110
+ },
111
+ {
112
+ value: "kanban",
113
+ label: "Board",
114
+ icon: <ViewKanbanIcon size="small" />
115
115
  }
116
116
  ];
117
117
 
118
- if (showKanban) {
119
- options.push({
120
- value: "kanban",
121
- label: "Board",
122
- icon: <ViewKanbanIcon size="small" />,
123
- disabled: !kanbanEnabled && !hasKanbanConfigPlugin
124
- });
125
- }
118
+ return allOptions.filter(option => enabledViews.includes(option.value));
119
+ }, [enabledViews]);
126
120
 
127
- return options;
128
- }, [showKanban, kanbanEnabled, hasKanbanConfigPlugin]);
121
+ // Don't render if only one view is enabled
122
+ if (viewModeOptions.length <= 1 && !showSizeSelector) {
123
+ return null;
124
+ }
129
125
 
130
126
  return (
131
127
  <Popover
@@ -141,11 +137,13 @@ export function ViewModeToggle({
141
137
  >
142
138
  <div className="p-3 flex flex-col gap-3 min-w-[240px]">
143
139
  {/* View mode toggle using ToggleButtonGroup */}
144
- <ToggleButtonGroup
145
- value={viewMode}
146
- onValueChange={onViewModeChange}
147
- options={viewModeOptions}
148
- />
140
+ {viewModeOptions.length > 1 && (
141
+ <ToggleButtonGroup
142
+ value={viewMode}
143
+ onValueChange={onViewModeChange}
144
+ options={viewModeOptions}
145
+ />
146
+ )}
149
147
 
150
148
  {/* Size selector */}
151
149
  {showSizeSelector && (
@@ -199,4 +197,3 @@ export function ViewModeToggle({
199
197
  </Popover>
200
198
  );
201
199
  }
202
-
@@ -374,6 +374,15 @@ export interface EntityCollection<M extends Record<string, any> = any, USER exte
374
374
  */
375
375
  defaultViewMode?: ViewMode;
376
376
 
377
+ /**
378
+ * Which view modes are available for this collection.
379
+ * Possible values: "table", "cards", "kanban".
380
+ * Defaults to all three: ["table", "cards", "kanban"].
381
+ * Note: "kanban" will only be available if the collection has at least
382
+ * one string property with enumValues defined, regardless of this setting.
383
+ */
384
+ enabledViews?: ViewMode[];
385
+
377
386
  /**
378
387
  * Configuration for Kanban board view mode.
379
388
  * When set, the Kanban view mode becomes available.