Skip to content

Commit 7353ae6

Browse files
Copilothotlong
andcommitted
Enhance actions with list_toolbar, visible/disabled expressions, bulkEnabled, and add msw-todo actions
- Add list_toolbar location + bulkEnabled to todo, CRM (account, contact, opportunity), and kitchen-sink actions - Add visible conditional expressions to opportunity (stage-gated), contact (type-gated), todo (status/completion-gated), showcase (status-gated) - Add 3 actions to msw-todo example (task_complete, task_reopen, task_delete) with batch + visible support - All 13/14 objects now have actions (kitchen_sink excluded as field-types demo) Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
1 parent 40b4b10 commit 7353ae6

File tree

6 files changed

+65
-7
lines changed

6 files changed

+65
-7
lines changed

examples/crm/src/actions/account.actions.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ export const AccountActions = [
1717
label: 'Assign Owner',
1818
icon: 'user-plus',
1919
type: 'api' as const,
20-
locations: ['record_header' as const, 'list_item' as const],
20+
locations: ['record_header' as const, 'list_item' as const, 'list_toolbar' as const],
21+
bulkEnabled: true,
2122
params: [
2223
{ name: 'owner_id', label: 'New Owner', type: 'lookup' as const, required: true },
2324
],

examples/crm/src/actions/contact.actions.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ export const ContactActions = [
44
label: 'Send Email',
55
icon: 'mail',
66
type: 'api' as const,
7-
locations: ['record_header' as const, 'list_item' as const],
7+
locations: ['record_header' as const, 'list_item' as const, 'list_toolbar' as const],
8+
bulkEnabled: true,
89
params: [
910
{ name: 'subject', label: 'Subject', type: 'text' as const, required: true },
1011
{ name: 'body', label: 'Message', type: 'textarea' as const },
@@ -17,6 +18,7 @@ export const ContactActions = [
1718
icon: 'user-check',
1819
type: 'api' as const,
1920
locations: ['record_header' as const],
21+
visible: "type !== 'Customer'",
2022
confirmText: 'Convert this contact to a customer?',
2123
refreshAfter: true,
2224
successMessage: 'Contact converted to customer',

examples/crm/src/actions/opportunity.actions.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ export const OpportunityActions = [
44
label: 'Change Stage',
55
icon: 'arrow-right-circle',
66
type: 'api' as const,
7-
locations: ['record_header' as const, 'list_item' as const],
7+
locations: ['record_header' as const, 'list_item' as const, 'list_toolbar' as const],
8+
bulkEnabled: true,
9+
visible: "stage !== 'closed_won' && stage !== 'closed_lost'",
810
params: [
911
{
1012
name: 'new_stage', label: 'New Stage', type: 'select' as const, required: true,
@@ -28,6 +30,7 @@ export const OpportunityActions = [
2830
type: 'api' as const,
2931
locations: ['record_header' as const],
3032
variant: 'primary' as const,
33+
visible: "stage !== 'closed_won' && stage !== 'closed_lost'",
3134
confirmText: 'Mark this opportunity as Closed Won?',
3235
refreshAfter: true,
3336
successMessage: 'Opportunity marked as won!',
@@ -39,6 +42,7 @@ export const OpportunityActions = [
3942
type: 'api' as const,
4043
locations: ['record_more' as const],
4144
variant: 'danger' as const,
45+
visible: "stage !== 'closed_won' && stage !== 'closed_lost'",
4246
params: [
4347
{ name: 'loss_reason', label: 'Reason for Loss', type: 'text' as const, required: true },
4448
],

examples/kitchen-sink/src/objects/showcase.actions.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ export const ShowcaseActions = [
44
label: 'Change Status',
55
icon: 'arrow-right-circle',
66
type: 'api' as const,
7-
locations: ['record_header' as const, 'list_item' as const],
7+
locations: ['record_header' as const, 'list_item' as const, 'list_toolbar' as const],
8+
bulkEnabled: true,
9+
visible: "status !== 'archived'",
810
params: [
911
{
1012
name: 'new_status', label: 'New Status', type: 'select' as const, required: true,
@@ -25,7 +27,8 @@ export const ShowcaseActions = [
2527
label: 'Assign Owner',
2628
icon: 'user-plus',
2729
type: 'api' as const,
28-
locations: ['record_header' as const],
30+
locations: ['record_header' as const, 'list_toolbar' as const],
31+
bulkEnabled: true,
2932
params: [
3033
{ name: 'owner_email', label: 'Owner Email', type: 'email' as const, required: true },
3134
{ name: 'notify', label: 'Send Notification', type: 'boolean' as const },
@@ -40,6 +43,7 @@ export const ShowcaseActions = [
4043
type: 'api' as const,
4144
locations: ['record_more' as const],
4245
variant: 'danger' as const,
46+
visible: "status !== 'archived'",
4347
confirmText: 'Are you sure you want to archive this item?',
4448
refreshAfter: true,
4549
successMessage: 'Item archived',

examples/msw-todo/objectstack.config.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,45 @@ export const TaskObject = ObjectSchema.create({
2626
},
2727
});
2828

29+
/**
30+
* Task Actions — complete, toggle, and delete operations
31+
*/
32+
export const TaskActions = [
33+
{
34+
name: 'task_complete',
35+
label: 'Mark Complete',
36+
icon: 'check-circle-2',
37+
type: 'api' as const,
38+
locations: ['record_header' as const, 'list_item' as const, 'list_toolbar' as const],
39+
visible: 'is_completed === false',
40+
bulkEnabled: true,
41+
refreshAfter: true,
42+
successMessage: 'Task completed',
43+
},
44+
{
45+
name: 'task_reopen',
46+
label: 'Reopen Task',
47+
icon: 'rotate-ccw',
48+
type: 'api' as const,
49+
locations: ['record_header' as const, 'list_item' as const],
50+
visible: 'is_completed === true',
51+
refreshAfter: true,
52+
successMessage: 'Task reopened',
53+
},
54+
{
55+
name: 'task_delete',
56+
label: 'Delete Task',
57+
icon: 'trash-2',
58+
type: 'api' as const,
59+
locations: ['record_more' as const, 'list_toolbar' as const],
60+
variant: 'danger' as const,
61+
bulkEnabled: true,
62+
confirmText: 'Are you sure you want to delete this task?',
63+
refreshAfter: true,
64+
successMessage: 'Task deleted',
65+
},
66+
];
67+
2968
/**
3069
* App Configuration — Standard ObjectStackDefinition format
3170
*/
@@ -47,6 +86,9 @@ export default defineStack({
4786
},
4887
},
4988
],
89+
actions: [
90+
...TaskActions,
91+
],
5092
apps: [
5193
App.create({
5294
name: 'task_app',

examples/todo/src/domains/todo/task.actions.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ export const TodoTaskActions = [
44
label: 'Mark Complete',
55
icon: 'check-circle-2',
66
type: 'api' as const,
7-
locations: ['record_header' as const, 'list_item' as const],
7+
locations: ['record_header' as const, 'list_item' as const, 'list_toolbar' as const],
8+
visible: 'is_completed === false',
9+
bulkEnabled: true,
810
confirmText: 'Mark this task as complete?',
911
refreshAfter: true,
1012
successMessage: 'Task marked as complete',
@@ -15,6 +17,7 @@ export const TodoTaskActions = [
1517
icon: 'play',
1618
type: 'api' as const,
1719
locations: ['record_header' as const, 'list_item' as const],
20+
visible: "status === 'Backlog' || status === 'Todo'",
1821
refreshAfter: true,
1922
successMessage: 'Task moved to In Progress',
2023
},
@@ -33,6 +36,7 @@ export const TodoTaskActions = [
3336
icon: 'clock',
3437
type: 'api' as const,
3538
locations: ['record_header' as const],
39+
visible: "status !== 'Done'",
3640
params: [
3741
{ name: 'defer_until', label: 'Defer Until', type: 'date' as const, required: true },
3842
],
@@ -56,7 +60,8 @@ export const TodoTaskActions = [
5660
label: 'Assign',
5761
icon: 'user-plus',
5862
type: 'api' as const,
59-
locations: ['record_header' as const, 'list_item' as const],
63+
locations: ['record_header' as const, 'list_item' as const, 'list_toolbar' as const],
64+
bulkEnabled: true,
6065
params: [
6166
{ name: 'assignee', label: 'Assignee', type: 'text' as const, required: true },
6267
],

0 commit comments

Comments
 (0)