@wix/auto-patterns 1.15.0 → 1.17.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.
Files changed (100) hide show
  1. package/dist/cjs/components/AutoPatternsCollectionPageContent/AutoPatternsCollectionPageContent.js +16 -4
  2. package/dist/cjs/components/AutoPatternsCollectionPageContent/AutoPatternsCollectionPageContent.js.map +1 -1
  3. package/dist/cjs/components/AutoPatternsCollectionPageContent/SkeletonCollection.js +34 -0
  4. package/dist/cjs/components/AutoPatternsCollectionPageContent/SkeletonCollection.js.map +1 -0
  5. package/dist/cjs/components/AutoPatternsEntityPage/AutoPatternsEntityPage.js +1 -0
  6. package/dist/cjs/components/AutoPatternsEntityPage/AutoPatternsEntityPage.js.map +1 -1
  7. package/dist/cjs/components/AutoPatternsEntityPage/SkeletonEntity.js +198 -0
  8. package/dist/cjs/components/AutoPatternsEntityPage/SkeletonEntity.js.map +1 -0
  9. package/dist/cjs/components/AutoPatternsRoute/AutoPatternsPage.js +13 -3
  10. package/dist/cjs/components/AutoPatternsRoute/AutoPatternsPage.js.map +1 -1
  11. package/dist/cjs/components/AutoPatternsRoute/AutoPatternsRoutes.js +4 -4
  12. package/dist/cjs/components/AutoPatternsRoute/AutoPatternsRoutes.js.map +1 -1
  13. package/dist/cjs/hooks/useBaseTableFeatures.js +7 -2
  14. package/dist/cjs/hooks/useBaseTableFeatures.js.map +1 -1
  15. package/dist/cjs/hooks/useCollectionPageOnRowClickActions.js +49 -0
  16. package/dist/cjs/hooks/useCollectionPageOnRowClickActions.js.map +1 -0
  17. package/dist/cjs/hooks/useNavigationUtils.js +2 -2
  18. package/dist/cjs/hooks/useNavigationUtils.js.map +1 -1
  19. package/dist/cjs/providers/PatternsWizardOverridesContext.js +1 -1
  20. package/dist/cjs/providers/PatternsWizardOverridesContext.js.map +1 -1
  21. package/dist/cjs/providers/SchemaContext.js +4 -3
  22. package/dist/cjs/providers/SchemaContext.js.map +1 -1
  23. package/dist/cjs/types/CollectionPageConfig.js.map +1 -1
  24. package/dist/cjs/types/actions/base.js.map +1 -1
  25. package/dist/cjs/types/actions/collectionPageActions.js.map +1 -1
  26. package/dist/cjs/utils/actions/resolveAction.js +2 -1
  27. package/dist/cjs/utils/actions/resolveAction.js.map +1 -1
  28. package/dist/cjs/utils/actions/types.js.map +1 -1
  29. package/dist/docs/action_cell.md +233 -0
  30. package/dist/docs/app_config_structure.md +356 -0
  31. package/dist/docs/auto-patterns-guide.md +2467 -0
  32. package/dist/docs/bulk_actions.md +266 -0
  33. package/dist/docs/collection_page.md +54 -0
  34. package/dist/docs/collection_page_actions.md +343 -0
  35. package/dist/docs/custom_overrides.md +511 -0
  36. package/dist/docs/entity_page.md +104 -0
  37. package/dist/docs/entity_page_actions.md +92 -0
  38. package/dist/docs/index.md +76 -0
  39. package/dist/docs/installation.md +55 -0
  40. package/dist/docs/introduction.md +74 -0
  41. package/dist/docs/pages_configuration.md +129 -0
  42. package/dist/docs/recipe-bulk-operations.md +1352 -0
  43. package/dist/docs/recipe-crud-operations.md +805 -0
  44. package/dist/docs/recipe-customization.md +1703 -0
  45. package/dist/docs/recipe-first-dashboard.md +795 -0
  46. package/dist/docs/sdk_and_schema.md +215 -0
  47. package/dist/esm/components/AutoPatternsCollectionPageContent/AutoPatternsCollectionPageContent.js +7 -1
  48. package/dist/esm/components/AutoPatternsCollectionPageContent/AutoPatternsCollectionPageContent.js.map +1 -1
  49. package/dist/esm/components/AutoPatternsCollectionPageContent/SkeletonCollection.js +21 -0
  50. package/dist/esm/components/AutoPatternsCollectionPageContent/SkeletonCollection.js.map +1 -0
  51. package/dist/esm/components/AutoPatternsEntityPage/AutoPatternsEntityPage.js +3 -1
  52. package/dist/esm/components/AutoPatternsEntityPage/AutoPatternsEntityPage.js.map +1 -1
  53. package/dist/esm/components/AutoPatternsEntityPage/SkeletonEntity.js +91 -0
  54. package/dist/esm/components/AutoPatternsEntityPage/SkeletonEntity.js.map +1 -0
  55. package/dist/esm/components/AutoPatternsRoute/AutoPatternsPage.js +5 -1
  56. package/dist/esm/components/AutoPatternsRoute/AutoPatternsPage.js.map +1 -1
  57. package/dist/esm/components/AutoPatternsRoute/AutoPatternsRoutes.js +1 -1
  58. package/dist/esm/components/AutoPatternsRoute/AutoPatternsRoutes.js.map +1 -1
  59. package/dist/esm/hooks/useBaseTableFeatures.js +6 -1
  60. package/dist/esm/hooks/useBaseTableFeatures.js.map +1 -1
  61. package/dist/esm/hooks/useCollectionPageOnRowClickActions.js +45 -0
  62. package/dist/esm/hooks/useCollectionPageOnRowClickActions.js.map +1 -0
  63. package/dist/esm/hooks/useNavigationUtils.js +1 -1
  64. package/dist/esm/hooks/useNavigationUtils.js.map +1 -1
  65. package/dist/esm/providers/PatternsWizardOverridesContext.js.map +1 -1
  66. package/dist/esm/providers/SchemaContext.js +3 -2
  67. package/dist/esm/providers/SchemaContext.js.map +1 -1
  68. package/dist/esm/types/CollectionPageConfig.js.map +1 -1
  69. package/dist/esm/types/actions/base.js.map +1 -1
  70. package/dist/esm/types/actions/collectionPageActions.js.map +1 -1
  71. package/dist/esm/utils/actions/resolveAction.js +2 -1
  72. package/dist/esm/utils/actions/resolveAction.js.map +1 -1
  73. package/dist/esm/utils/actions/types.js.map +1 -1
  74. package/dist/types/components/AutoPatternsCollectionPageContent/AutoPatternsCollectionPageContent.d.ts.map +1 -1
  75. package/dist/types/components/AutoPatternsCollectionPageContent/SkeletonCollection.d.ts +5 -0
  76. package/dist/types/components/AutoPatternsCollectionPageContent/SkeletonCollection.d.ts.map +1 -0
  77. package/dist/types/components/AutoPatternsEntityPage/SkeletonEntity.d.ts +7 -0
  78. package/dist/types/components/AutoPatternsEntityPage/SkeletonEntity.d.ts.map +1 -0
  79. package/dist/types/components/AutoPatternsRoute/AutoPatternsPage.d.ts.map +1 -1
  80. package/dist/types/hooks/useBaseTableFeatures.d.ts +1 -1
  81. package/dist/types/hooks/useBaseTableFeatures.d.ts.map +1 -1
  82. package/dist/types/hooks/useCollectionPageOnRowClickActions.d.ts +7 -0
  83. package/dist/types/hooks/useCollectionPageOnRowClickActions.d.ts.map +1 -0
  84. package/dist/types/hooks/useTableFeatures.d.ts +1 -1
  85. package/dist/types/hooks/useTableGridSwitchFeatures.d.ts +1 -1
  86. package/dist/types/providers/PatternsWizardOverridesContext.d.ts +2 -2
  87. package/dist/types/providers/PatternsWizardOverridesContext.d.ts.map +1 -1
  88. package/dist/types/providers/SchemaContext.d.ts +2 -1
  89. package/dist/types/providers/SchemaContext.d.ts.map +1 -1
  90. package/dist/types/types/CollectionPageConfig.d.ts +2 -1
  91. package/dist/types/types/CollectionPageConfig.d.ts.map +1 -1
  92. package/dist/types/types/actions/base.d.ts +1 -0
  93. package/dist/types/types/actions/base.d.ts.map +1 -1
  94. package/dist/types/types/actions/collectionPageActions.d.ts +8 -0
  95. package/dist/types/types/actions/collectionPageActions.d.ts.map +1 -1
  96. package/dist/types/utils/actions/resolveAction.d.ts +1 -0
  97. package/dist/types/utils/actions/resolveAction.d.ts.map +1 -1
  98. package/dist/types/utils/actions/types.d.ts +1 -0
  99. package/dist/types/utils/actions/types.d.ts.map +1 -1
  100. package/package.json +26 -20
@@ -0,0 +1,266 @@
1
+ ## Bulk Action Toolbar Configuration
2
+
3
+ The Bulk Action Toolbar feature enables users to perform operations on multiple selected entities simultaneously in collection tables or grids. When configured, it adds checkboxes to each row and displays a toolbar with bulk actions when items are selected.
4
+
5
+ ### Placement and Structure
6
+
7
+ The Bulk Action Toolbar is configured within the table / grid / table-grid switch configuration using the `bulkActionToolbar` property. It has a two-level structure:
8
+ * `primaryActions`: Actions shown directly in the bulk action toolbar
9
+ * `secondaryActions`: Additional actions organized in sections, typically shown in a dropdown menu
10
+
11
+ Both properties are optional, but at least one should be provided for the bulk action toolbar to be functional.
12
+
13
+ ### Bulk Action Types Reference
14
+
15
+ 1. **Bulk Delete Action** (`type: "bulkDelete"`):
16
+ - ✓ Use when: Removing multiple entities with confirmation
17
+ - ✓ Common scenarios:
18
+ - Mass deletion of records
19
+ - Bulk cleanup operations
20
+ - ✓ Built-in functionality: No custom implementation needed
21
+
22
+ 2. **Custom Action** (`type: "custom"`):
23
+ - ✓ Use when: Executing custom JavaScript for bulk operations
24
+ - ✓ Common scenarios:
25
+ - Bulk API calls
26
+ - Bulk exports/downloads
27
+ - Complex bulk operations without UI
28
+ - ⚠️ Requires implementation: Must register action in overrides
29
+
30
+ ### Type Selection Decision Tree
31
+
32
+ When choosing a bulk action type, follow this decision process:
33
+
34
+ 1. IF removing multiple entities:
35
+ → Use `type: "bulkDelete"`
36
+
37
+ 2. IF executing custom logic for bulk operations without UI:
38
+ → Use `type: "custom"`
39
+ - MUST implement action handler
40
+ - MUST register with `actions` override
41
+
42
+ ### Bulk Delete Action Configuration
43
+
44
+ Bulk delete actions remove multiple entities with a confirmation modal.
45
+
46
+ #### Validation Rules:
47
+
48
+ 1. `bulkDelete.mode` must be `"modal"` (currently only modal is supported)
49
+ 2. `bulkDelete.modal` object must exist
50
+ 3. The modal properties (title, description, actions, feedback) are all optional
51
+
52
+ ### Custom Bulk Action Configuration
53
+
54
+ Custom bulk actions execute JavaScript code that you define for bulk operations. These actions receive parameters that give them access to selected entities data and utilities. Here's how to implement a custom bulk action:
55
+
56
+ 1. First, create the actions folder structure in your page folder:
57
+ ```
58
+ your-page/
59
+ ├── page.tsx
60
+ └── components/
61
+ └── actions/
62
+ ├── index.tsx // Exports all actions
63
+ └── bulkExportPets.tsx // Your custom bulk action
64
+ ```
65
+
66
+ 2. Create your bulk action handler in `bulkExportPets.tsx`:
67
+ ```typescript
68
+ import { CustomBulkActionsActionResolver } from '@wix/auto-patterns';
69
+ import { Download } from '@wix/wix-ui-icons-common';
70
+ import React from 'react';
71
+
72
+ // IMPORTANT: Function name MUST match the action id in your configuration
73
+ export const bulkExportPets: CustomBulkActionsActionResolver = (params) => {
74
+ const { actionParams, sdk } = params;
75
+ const { selectedValues, total } = actionParams;
76
+
77
+ return {
78
+ label: 'Export Selected',
79
+ icon: <Download />,
80
+ onClick: () => {
81
+ // sdk is provided to custom action resolvers (see SDK Utilities section)
82
+ const optimisticActions = sdk.getOptimisticActions(sdk.collectionId);
83
+ const schema = sdk.getSchema(sdk.collectionId);
84
+
85
+ // Example: Mark pets as exported
86
+ const updatedItems = selectedValues.map(item => ({
87
+ ...item,
88
+ lastExported: new Date()
89
+ }));
90
+ optimisticActions.updateMany(updatedItems, {
91
+ submit: async (items) => {
92
+ // Your export logic here + update server
93
+ const exportData = items.map(pet => ({
94
+ name: pet.name,
95
+ age: pet.age,
96
+ owner: pet.owner
97
+ }));
98
+
99
+ // Create and download CSV
100
+ const csv = exportData.map(row => Object.values(row).join(',')).join('\n');
101
+ const blob = new Blob([csv], { type: 'text/csv' });
102
+ const url = URL.createObjectURL(blob);
103
+ const a = document.createElement('a');
104
+ a.href = url;
105
+ a.download = 'pets-export.csv';
106
+ a.click();
107
+
108
+ // Update server with export timestamp
109
+ return await schema.actions.update(items);
110
+ },
111
+ successToast: `${selectedValues.length} pets exported`,
112
+ errorToast: (err, {retry}) => ({
113
+ text: 'Export failed',
114
+ action: { text: 'Retry', onClick: retry }
115
+ })
116
+ });
117
+ },
118
+ };
119
+ };
120
+ ```
121
+
122
+ 3. Export your action in `actions/index.tsx`:
123
+ ```typescript
124
+ export * from './bulkExportPets';
125
+ ```
126
+
127
+ 4. Configure the action in your JSON configuration:
128
+ ```json
129
+ {
130
+ "id": "bulkExportPets", // MUST match the function name exactly
131
+ "type": "custom", // REQUIRED: Must be exactly "custom"
132
+ "label": "Export Selected", // Optional: Displayed text
133
+ }
134
+ ```
135
+
136
+ 5. Register your action in the `PatternsWizardOverridesProvider`:
137
+ ```typescript
138
+ import * as actions from './components/actions';
139
+
140
+ <PatternsWizardOverridesProvider value={{ actions }}>
141
+ <AutoPatternsApp configuration={config as AppConfig} />
142
+ </PatternsWizardOverridesProvider>
143
+ ```
144
+
145
+ ### Key Points for Custom Bulk Actions:
146
+ - The action `id` in the configuration MUST exactly match the function name exported from your actions folder
147
+ - The function name and file name should follow a consistent naming convention (e.g., camelCase)
148
+ - The implementation must be exported as a named export (not default export)
149
+ - The implementation must use the `CustomBulkActionsActionResolver` type
150
+ - Access selected entities through `actionParams.selectedValues`
151
+ - Access total count through `actionParams.total`
152
+
153
+ #### Validation Rules for Custom Bulk Actions:
154
+
155
+ 1. `id` must:
156
+ - Match exactly the function name of the custom bulk action implementation
157
+ - Be registered in the `actions` property of your `PatternsWizardOverridesProvider`
158
+ - Follow JavaScript identifier naming rules (camelCase recommended)
159
+
160
+ 2. The implementation must return an object with:
161
+ - `label`: Text displayed for the action
162
+ - `icon`: An Icon component from "@wix/wix-ui-icons-common"
163
+ - `onClick`: Handler function for the bulk action
164
+
165
+ 3. The implementation must:
166
+ - Use the correct type: `CustomBulkActionsActionResolver`
167
+ - Be exported as a named export
168
+ - Have a filename matching the function name
169
+
170
+ ### Bulk Action Toolbar Structure
171
+
172
+ The bulk action toolbar uses a specific structure for organizing actions:
173
+
174
+ #### Primary Actions Structure:
175
+ ```json
176
+ "bulkActionToolbar": {
177
+ "primaryActions": [
178
+ {
179
+ "type": "action",
180
+ "action": {
181
+ "item": {
182
+ "id": "bulkCustom",
183
+ "type": "custom",
184
+ "label": "Custom Bulk",
185
+ "custom": {
186
+ "id": "MyCustomBulk"
187
+ }
188
+ }
189
+ }
190
+ },
191
+ {
192
+ "type": "menu",
193
+ "menu": {
194
+ "label": "More actions",
195
+ "items": [
196
+ {
197
+ "id": "exportItems",
198
+ "type": "custom",
199
+ "label": "Export Items"
200
+ },
201
+ { "type": "divider" },
202
+ {
203
+ "id": "downloadItems",
204
+ "type": "custom",
205
+ "label": "Download Items"
206
+ }
207
+ ]
208
+ }
209
+ }
210
+ ]
211
+ }
212
+ ```
213
+
214
+ #### Secondary Actions Structure:
215
+ ```json
216
+ "bulkActionToolbar": {
217
+ "secondaryActions": [
218
+ {
219
+ "id": "bulkDeleteWithModal",
220
+ "label": "Bulk Delete",
221
+ "type": "bulkDelete",
222
+ "bulkDelete": {
223
+ "mode": "modal",
224
+ "modal": {
225
+ "title": { "text": "Delete items" },
226
+ "description": { "text": "Are you sure?" }
227
+ }
228
+ }
229
+ },
230
+ {
231
+ "id": "bulkExportPets",
232
+ "type": "custom",
233
+ "label": "Export Selected"
234
+ }
235
+ ]
236
+ }
237
+ ```
238
+
239
+ ### Key Implementation Decisions
240
+
241
+ Follow this decision process when implementing Bulk Action Toolbar:
242
+
243
+ 1. **Basic Decision**: Decide which bulk operations users need to perform:
244
+ - Delete multiple entities? → Use `bulkDelete` actions
245
+ - Custom bulk operations? → Use `custom` actions
246
+
247
+ 2. **Primary vs Secondary**: Choose the most common/important bulk action as primary:
248
+ - Most common bulk operation → Place in `primaryActions.items` array
249
+ - Less common bulk operations → Place in `secondaryActions` array
250
+
251
+ 3. **Custom Implementation**:
252
+ - For `custom` bulk actions, you must provide implementations in your code and register them with `PatternsWizardOverridesProvider`
253
+
254
+ ### Bulk Action Toolbar Validation Checklist
255
+
256
+ AI agents should verify these requirements before generating Bulk Action Toolbar configurations:
257
+
258
+ ✓ Bulk Action Toolbar is placed directly inside `table` or `grid` configuration as `bulkActionToolbar`
259
+ ✓ Each bulk action has a unique `id` and correct `type` value
260
+ ✓ Each action type only includes its required field(s)
261
+ ✓ Bulk delete actions have modal configuration
262
+ ✓ Custom bulk actions match implementations in overrides
263
+ ✓ At least one of `primaryActions` or `secondaryActions` is provided
264
+ ✓ Primary actions use `action`/`menu` structure with proper `action` or `menu` properties
265
+ ✓ Secondary actions are an array that can include dividers
266
+ ✓ Menu items within primary actions is array that can include dividers
@@ -0,0 +1,54 @@
1
+ # Collection Page Configuration
2
+
3
+ ## ⚠️ Collection Page Rules
4
+
5
+ - **Components array inside collectionPage must contain exactly one component with a layout array**
6
+ - **All collection pages with tables/grids must reference their corresponding entity page via `entityPageId`** in the collection configuration
7
+ - **Enable `customColumns` only based on strict logic** - enable if more than 5 columns are defined OR user explicitly requests it, otherwise disable
8
+ - **Row click behavior**: By default, clicking a table row navigates to the entity page. Use `onRowClick` configuration only when custom row click behavior is explicitly required
9
+ - **When generating config for first time, select up to 3 columns from the schema that best represent the entity**
10
+
11
+ ## Components Array
12
+
13
+ * Must include **exactly one item**.
14
+ * Each component must have:
15
+ * `collection`: Collection configuration with `collectionId` and `entityTypeSource: 'cms'`
16
+ * `layout`: Array of layout items that determine what components to render
17
+
18
+ ## Layout Array
19
+
20
+ The `layout` array contains the rendering components for the collection. Each layout item has:
21
+ * `type`: Either 'Table' or 'Grid'
22
+ * Component-specific configuration (`table` or `grid` object)
23
+
24
+ ### Layout Item Types:
25
+
26
+ 1. **Table Layout Item** (`type: 'Table'`):
27
+ * `table` field contains table-specific configuration
28
+ * Used for displaying collection in a **table view**
29
+ * Includes columns, actionCell, bulkActionToolbar, etc.
30
+
31
+ 2. **Grid Layout Item** (`type: 'Grid'`):
32
+ * `grid` field contains grid-specific configuration
33
+ * Used for **grid (card) view** of collection
34
+ * Includes item configuration for title/subtitle/image fields
35
+
36
+ ### Table/Grid View Switch Behavior:
37
+ * When **both** Table and Grid layout items are present in the layout array, AutoPatterns automatically adds a Table/Grid view switch control so users can toggle between the two views
38
+ * Users can toggle between table and grid views
39
+
40
+ ## Table Configuration
41
+
42
+ * Used for displaying collection in a **table view**.
43
+ * **customColumns.enabled** logic:
44
+ * Enable if:
45
+ * More than **5 columns** are defined
46
+ * OR user **explicitly** requests it
47
+ * Otherwise, **disable** (false)
48
+
49
+ ## Grid Configuration
50
+
51
+ * Used for **grid (card) view** of collection.
52
+ * `item.title`, `item.subtitle`, `item.image` fields are **Field IDs** from the schema.
53
+ * If the user does not specify, **select the most relevant fields automatically**.
54
+ * For grid components, it is strongly recommended to implement a primary action cell with an `update` action that navigates to the entity page. This provides users with an intuitive way to access detailed information and edit individual entities directly from the grid view.
@@ -0,0 +1,343 @@
1
+ # Collection Page Actions
2
+
3
+ ## ⚠️ Required Actions
4
+
5
+ - **Every collection page must include a create action that navigates to the entity page for adding new entities** - this is essential for user workflow
6
+
7
+ The `actions` property is an optional object within the `collectionPage` configuration, but it is strongly recommended to always include primaryActions with a create action for better user experience.
8
+
9
+ ## `primaryActions` and `secondaryActions` Structure
10
+
11
+ Both `primaryActions` and `secondaryActions` are optional and share the same underlying structure for defining how actions are displayed. They can be configured in one of two ways:
12
+
13
+ ### A. Action Layout (`type: "action"`)
14
+ * **Description**: This layout is used to display a single, prominent page-level action. For example, a "Create New Item" button.
15
+ * **`action.item`**: Contains the configuration for the single action.
16
+
17
+ ### B. Action Menu Layout (`type: "menu"`)
18
+ * **Description**: This layout groups several page-level actions, often rendered as a dropdown menu or a set of related buttons under a common label.
19
+ * **`menu.label`**: A string that serves as the title or accessible label for the group of actions.
20
+ * **`menu.items`**: A flat array of action configurations, which can include divider objects for visual separation.
21
+
22
+ ## Individual Action Configuration
23
+
24
+ Each individual action, whether standalone in an `action` layout or part of an `items` array in a `menu` layout, is defined by the action item structure (see `AppConfig Structure`).
25
+
26
+ In addition to these common properties, each action item must specify a `type` which determines the action's behavior and additional required configuration.
27
+
28
+ ### 1. `type: "create"`
29
+ * **Purpose**: Navigates to an entity page, allowing the user to create a new item in the specified collection.
30
+ * **Details**:
31
+ * `create.mode`: Must be `'page'`.
32
+ * `create.page.id`: Must be the `id` of an existing `entityPage` in your `AppConfig`. This entity page should be set up to handle the creation of new entities for the `collection.collectionId`.
33
+
34
+ ### 2. `type: "custom"`
35
+ * **Purpose**: Executes custom JavaScript logic defined in your application's overrides.
36
+ * **Details**:
37
+ * The `custom` object in the configuration is typically empty. The functionality is determined by a custom action resolver function that you implement and register in the `actions` section of your `PatternsWizardOverridesProvider`. The `id` of this action item must exactly match the name (key) of the registered custom action resolver. The resolver will receive parameters including `collectionId`.
38
+
39
+ ### 3. `type: "divider"`
40
+ * **Purpose**: Creates a visual separator between action groups in menus and lists.
41
+ * **Details**:
42
+ * Divider actions require no additional configuration beyond `{ "type": "divider" }`.
43
+ * Used within flat arrays to create logical groupings.
44
+
45
+ ## Note on `secondaryActions`
46
+
47
+ `secondaryActions` follow the exact same structural rules (`type: "action"` or `type: "menu"`) and use the same action item options as `primaryActions`. They are typically used for less prominent or less frequently used page-level actions, often rendered in a secondary position or within a "more options" style menu.
48
+
49
+ ## Custom Collection Page Action Configuration
50
+
51
+ Custom collection page actions execute JavaScript code that you define for collection-level operations. These actions receive parameters that give them access to collection context and utilities. Here's how to implement a custom collection page action:
52
+
53
+ 1. First, create the actions folder structure in your page folder:
54
+ ```
55
+ your-page/
56
+ ├── page.tsx
57
+ └── components/
58
+ └── actions/
59
+ ├── index.tsx // Exports all actions
60
+ └── exportCollection.tsx // Your custom collection action
61
+ ```
62
+
63
+ 2. Create your collection action handler in `exportCollection.tsx`:
64
+ ```typescript
65
+ import { CustomActionCollectionPageActionResolver } from '@wix/auto-patterns';
66
+ import React from 'react';
67
+ import { Download } from '@wix/ui-icons-common';
68
+
69
+ // IMPORTANT: Function name MUST match the action id in your configuration
70
+ export const exportCollection: CustomActionCollectionPageActionResolver = (params) => {
71
+ const { actionParams, sdk } = params;
72
+ const { collectionId } = actionParams;
73
+
74
+ return {
75
+ label: 'Export Collection',
76
+ icon: <Download />,
77
+ onClick: () => {
78
+ // sdk is provided to custom action resolvers (see SDK Utilities section)
79
+ const optimisticActions = sdk.getOptimisticActions(collectionId);
80
+ const schema = sdk.getSchema(collectionId);
81
+
82
+ // Example: Mark entire collection as exported
83
+ optimisticActions.updateAll(
84
+ (item) => ({ lastExported: new Date() }),
85
+ {
86
+ submit: async () => {
87
+ // Your collection export logic here
88
+ console.log(`Exporting collection: ${collectionId}`);
89
+ // Export and update all items on server
90
+ return await schema.actions.bulkUpdate({ lastExported: new Date() });
91
+ },
92
+ successToast: 'Collection exported successfully',
93
+ errorToast: (err, {retry}) => ({
94
+ text: 'Export failed',
95
+ action: { text: 'Retry', onClick: retry }
96
+ })
97
+ }
98
+ );
99
+ },
100
+ };
101
+ };
102
+ ```
103
+
104
+ 3. Export your action in `actions/index.tsx`:
105
+ ```typescript
106
+ export * from './exportCollection';
107
+ ```
108
+
109
+ 4. Configure the action in your JSON configuration:
110
+ ```json
111
+ {
112
+ "id": "exportCollection", // MUST match the function name exactly
113
+ "type": "custom", // REQUIRED: Must be exactly "custom"
114
+ "label": "Export Collection", // Optional: Displayed text
115
+ "collection": {
116
+ "collectionId": "WixPets",
117
+ "entityTypeSource": "cms"
118
+ }
119
+ }
120
+ ```
121
+
122
+ 5. Register your action in the `PatternsWizardOverridesProvider`:
123
+ ```typescript
124
+ import * as actions from './components/actions';
125
+
126
+ <PatternsWizardOverridesProvider value={{ actions }}>
127
+ <AutoPatternsApp configuration={config as AppConfig} />
128
+ </PatternsWizardOverridesProvider>
129
+ ```
130
+
131
+ ## Key Points for Custom Collection Page Actions:
132
+ - The action `id` in the configuration MUST exactly match the function name exported from your actions folder
133
+ - The function name and file name should follow a consistent naming convention (e.g., camelCase)
134
+ - The implementation must be exported as a named export (not default export)
135
+ - The implementation must use the `CustomActionCollectionPageActionResolver` type
136
+ - Access collection context through `actionParams.collectionId`
137
+
138
+ ---
139
+
140
+ ## Custom Row Click Actions
141
+
142
+ In addition to page-level actions, you can also customize what happens when users click on individual rows in your collection table. By default, clicking a row navigates to the entity page, but you can override this behavior with custom logic.
143
+
144
+ **Before You Start:**
145
+ - Only configure `onRowClick` if you need custom behavior (e.g., opening modals, side panels, custom actions)
146
+ - If you just want navigation to entity page, don't configure `onRowClick` - it's the default behavior
147
+ - Once you configure `onRowClick`, you must provide a complete working implementation
148
+
149
+ ### Configuration
150
+
151
+ Row click actions are configured at the table level using the `onRowClick` property:
152
+
153
+ ```json
154
+ {
155
+ "type": "Table",
156
+ "table": {
157
+ "columns": [...],
158
+ "onRowClick": {
159
+ "id": "handleRowClick", // MUST match the function name exactly
160
+ "type": "custom", // REQUIRED: Must be exactly "custom"
161
+ }
162
+ }
163
+ }
164
+ ```
165
+
166
+ ### Implementation Requirements
167
+
168
+ ⚠️ **CRITICAL**: When you configure `onRowClick` in your JSON, you MUST provide a complete working implementation. The Auto Patterns framework cannot function without it.
169
+
170
+ Custom row click actions use the `CustomActionCollectionPageActionOnRowClickResolver` type and MUST return a `ResolvedAction` object with all required properties:
171
+
172
+ #### Required Return Object Structure:
173
+ ```typescript
174
+ return {
175
+ label: string, // REQUIRED: Action label
176
+ icon: ReactElement, // REQUIRED: Icon component
177
+ onClick: () => void // REQUIRED: Click handler function
178
+ };
179
+ ```
180
+
181
+ #### Complete Implementation Example:
182
+
183
+ ```typescript
184
+ import { CustomActionCollectionPageActionOnRowClickResolver } from '@wix/auto-patterns';
185
+ import React from 'react';
186
+ import { More } from '@wix/wix-ui-icons-common';
187
+
188
+ // IMPORTANT: Function name MUST match the action id in your configuration
189
+ export const handleRowClick: CustomActionCollectionPageActionOnRowClickResolver = (params) => {
190
+ const { actionParams, sdk } = params;
191
+ const { item } = actionParams; // The clicked row's data
192
+
193
+ return {
194
+ label: 'View Details', // REQUIRED
195
+ icon: <More />, // REQUIRED
196
+ onClick: () => { // REQUIRED
197
+ // Your custom row click logic here
198
+ console.log('Row clicked:', item);
199
+
200
+ // Example: Show a custom modal, perform an action, etc.
201
+ // You can access all SDK utilities here (see SDK Utilities section)
202
+ const optimisticActions = sdk.getOptimisticActions(sdk.collectionId);
203
+ const schema = sdk.getSchema(sdk.collectionId);
204
+
205
+ // Your custom logic...
206
+ },
207
+ };
208
+ };
209
+ ```
210
+
211
+ ### Common Use Cases and Complete Examples
212
+
213
+ #### 1. Opening a Side Panel Modal
214
+
215
+ This is a complete working example for opening a side panel when clicking a row:
216
+
217
+ **Step 1: Create the row click action** (`components/actions/openSidePanel.tsx`):
218
+ ```typescript
219
+ import { CustomActionCollectionPageActionOnRowClickResolver } from '@wix/auto-patterns';
220
+ import React from 'react';
221
+ import { More } from '@wix/wix-ui-icons-common';
222
+
223
+ export const openSidePanel: CustomActionCollectionPageActionOnRowClickResolver = (params) => {
224
+ const { actionParams, sdk } = params;
225
+ const { item } = actionParams;
226
+
227
+ return {
228
+ label: 'View Details',
229
+ icon: <More />,
230
+ onClick: () => {
231
+ // Open a custom modal with the item data
232
+ // You need to implement the modal opening mechanism
233
+ // This could be through a modal context, state management, etc.
234
+ console.log('Opening side panel for:', item);
235
+
236
+ // Example: Using a global modal state (you need to implement this)
237
+ // window.dispatchEvent(new CustomEvent('openSidePanel', { detail: item }));
238
+
239
+ // Or use a modal service/context that you've set up
240
+ // modalService.openSidePanel(item);
241
+ },
242
+ };
243
+ };
244
+ ```
245
+
246
+ **Step 2: Configure in JSON**:
247
+ ```json
248
+ {
249
+ "type": "Table",
250
+ "table": {
251
+ "onRowClick": {
252
+ "id": "openSidePanel",
253
+ "type": "custom"
254
+ },
255
+ "columns": [...]
256
+ }
257
+ }
258
+ ```
259
+
260
+ **Step 3: Export and Register**:
261
+ ```typescript
262
+ // components/actions/index.tsx
263
+ export * from './openSidePanel';
264
+
265
+ // page.tsx
266
+ import * as actions from './components/actions';
267
+
268
+ <PatternsWizardOverridesProvider value={{ actions }}>
269
+ <AutoPatternsApp configuration={config as AppConfig} />
270
+ </PatternsWizardOverridesProvider>
271
+ ```
272
+
273
+ #### 2. Direct Data Manipulation
274
+
275
+ ```typescript
276
+ export const quickToggle: CustomActionCollectionPageActionOnRowClickResolver = (params) => {
277
+ const { actionParams, sdk } = params;
278
+ const { item } = actionParams;
279
+
280
+ return {
281
+ label: 'Quick Toggle',
282
+ icon: <Toggle />,
283
+ onClick: () => {
284
+ const optimisticActions = sdk.getOptimisticActions(sdk.collectionId);
285
+ const schema = sdk.getSchema(sdk.collectionId);
286
+
287
+ // Example: Toggle a boolean field
288
+ const updatedItem = { ...item, isActive: !item.isActive };
289
+
290
+ optimisticActions.updateOne(updatedItem, {
291
+ submit: async (items) => schema.actions.update(items[0]),
292
+ successToast: `${item.name} toggled successfully`,
293
+ errorToast: (err, {retry}) => ({
294
+ text: 'Toggle failed',
295
+ action: { text: 'Retry', onClick: retry }
296
+ })
297
+ });
298
+ },
299
+ };
300
+ };
301
+ ```
302
+
303
+ ### Default vs Custom Behavior
304
+
305
+ **Default Behavior (when `onRowClick` is not configured):**
306
+ - Clicking a row automatically navigates to the entity page
307
+ - Uses the `entityPageId` configuration to determine the target page
308
+ - Passes the selected item's data to the entity page
309
+
310
+ **Custom Behavior (when `onRowClick` is configured):**
311
+ - Default navigation is **disabled**
312
+ - Your custom action function is executed instead
313
+ - You have complete control over the row click behavior
314
+ - You can still navigate to the entity page programmatically if needed using the SDK navigation utilities
315
+
316
+ ### Key Points for Custom Row Click Actions:
317
+ - **MANDATORY IMPLEMENTATION**: If you configure `onRowClick` in JSON, you MUST provide a complete working implementation - the framework cannot function without it
318
+ - The action `id` in the configuration MUST exactly match the function name exported from your actions folder
319
+ - The implementation must use the `CustomActionCollectionPageActionOnRowClickResolver` type
320
+ - **Required Return Object**: Must return an object with `label`, `icon`, and `onClick` properties - all are required
321
+ - Access the clicked item's data through `actionParams.item`
322
+ - The implementation must be exported as a named export and registered in your `PatternsWizardOverridesProvider`
323
+ - When `onRowClick` is configured, the default navigation to entity page is completely disabled
324
+ - **Complete Setup Required**: You need to create the action file, export it in the index, and register it in the provider - missing any step will cause errors
325
+
326
+ ## Validation Checklist for Collection Page Actions
327
+
328
+ ✓ Every collection page must include a create action.
329
+ ✓ `actions` is an optional property of `collectionPage`.
330
+ ✓ `primaryActions` and `secondaryActions` (if defined) have a valid `type` ("action" or "menu").
331
+ ✓ If `type: "action"`, `action.item` is a valid action item configuration.
332
+ ✓ If `type: "menu"`, `menu.items` is an array of valid action item configurations that can include dividers.
333
+ ✓ Each action item contains a unique `id`, and the full `collection` object (`collectionId`, `entityTypeSource: 'cms'`).
334
+ ✓ Each action item has a supported `type` (`create`, `custom`) and its corresponding configuration block (e.g., `create` block for `type: "create"`).
335
+ ✓ `create` actions specify a `create.page.id` that matches an existing `entityPage` ID in the configuration.
336
+ ✓ `custom` actions (identified by their main `id`) correspond to an action resolver function name registered in the `actions` override.
337
+ ✓ Divider actions use `{ "type": "divider" }` format and require no additional properties.
338
+ ✓ If `onRowClick` is configured in table layout, it must have a valid `id` and `type: "custom"`.
339
+ ✓ **CRITICAL**: Custom row click actions must have corresponding implementations registered in the `actions` override - configuration without implementation will cause errors.
340
+ ✓ Custom row click action implementations must return an object with `label`, `icon`, and `onClick` properties - all are required.
341
+ ✓ Custom row click action implementations must be exported as named exports and included in the actions index file.
342
+ ✓ `onRowClick` is optional - when not configured, rows navigate to entity page by default.
343
+ ✓ **IMPORTANT**: Configuring `onRowClick` completely disables default navigation - you must handle all row click logic in your custom implementation.