Skip to content

Commit 28684f1

Browse files
committed
feat: add default configuration for custom actions show options
1 parent dae9dac commit 28684f1

File tree

4 files changed

+163
-0
lines changed

4 files changed

+163
-0
lines changed
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
# Actions
2+
3+
You might need to give admin users a feature to perform some action on a single record. Actions can be displayed as buttons in the list view and/or in the three-dots menu.
4+
5+
Here's how to add a custom action:
6+
7+
```ts title="./resources/apartments.ts"
8+
{
9+
resourceId: 'aparts',
10+
options: {
11+
actions: [
12+
{
13+
name: 'Auto submit', // Display name of the action
14+
icon: 'flowbite:play-solid', // Icon to display (using Flowbite icons)
15+
16+
// Control who can see/use this action
17+
allowed: ({ adminUser, standardAllowedActions }) => {
18+
return true; // Allow everyone
19+
},
20+
21+
// Handler function when action is triggered
22+
action: ({ recordId, adminUser }) => {
23+
console.log("auto submit", recordId, adminUser);
24+
return {
25+
ok: true,
26+
successMessage: "Auto submitted"
27+
};
28+
},
29+
30+
// Configure where the action appears
31+
showIn: {
32+
list: true, // Show in list view
33+
showButton: true, // Show as a button
34+
showThreeDotsMenu: true, // Show in three-dots menu
35+
}
36+
}
37+
]
38+
}
39+
}
40+
```
41+
42+
## Action Configuration Options
43+
44+
- `name`: Display name of the action
45+
- `icon`: Icon to show (using Flowbite icon set)
46+
- `allowed`: Function to control access to the action
47+
- `action`: Handler function that executes when action is triggered
48+
- `showIn`: Controls where the action appears
49+
- `list`: Show in list view
50+
- `showButton`: Show as a button
51+
- `showThreeDotsMenu`: Show in three-dots menu
52+
53+
## Access Control
54+
55+
You can control who can use an action through the `allowed` function. This function receives:
56+
57+
```ts title="./resources/apartments.ts"
58+
{
59+
options: {
60+
actions: [
61+
{
62+
name: 'Auto submit',
63+
allowed: ({ adminUser, standardAllowedActions }) => {
64+
if (adminUser.dbUser.role !== 'superadmin') {
65+
return false;
66+
}
67+
return true;
68+
},
69+
// ... other configuration
70+
}
71+
]
72+
}
73+
}
74+
```
75+
76+
The `allowed` function receives:
77+
- `adminUser`: The current admin user object
78+
- `standardAllowedActions`: Standard permissions for the current user
79+
80+
Return:
81+
- `true` to allow access
82+
- `false` to deny access
83+
- A string with an error message to explain why access was denied
84+
85+
Here is how it looks:
86+
![alt text](<Custom bulk actions.png>)
87+
88+
89+
You might want to allow only certain users to perform your custom bulk action.
90+
91+
To implement this limitation use `allowed`:
92+
93+
If you want to prohibit the use of bulk action for user, you can do it this way:
94+
95+
```ts title="./resources/apartments.ts"
96+
bulkActions: [
97+
{
98+
label: 'Mark as listed',
99+
icon: 'flowbite:eye-solid',
100+
state:'active',
101+
allowed: async ({ resource, adminUser, selectedIds }) => {
102+
if (adminUser.dbUser.role !== 'superadmin') {
103+
return false;
104+
}
105+
return true;
106+
},
107+
confirm: 'Are you sure you want to mark all selected apartments as listed?',
108+
action: function ({selectedIds, adminUser }: {selectedIds: any[], adminUser: AdminUser }, allow) {
109+
const stmt = admin.resource('aparts').dataConnector.db.prepare(`UPDATE apartments SET listed = 1 WHERE id IN (${selectedIds.map(() => '?').join(',')}`);
110+
stmt.run(...selectedIds);
111+
return { ok: true, error: false, successMessage: `Marked ${selectedIds.length} apartments as listed` };
112+
},
113+
}
114+
],
115+
```
116+
117+
## Action URL
118+
119+
Instead of defining an `action` handler, you can specify a `url` that the user will be redirected to when clicking the action button:
120+
121+
```ts title="./resources/apartments.ts"
122+
{
123+
name: 'View details',
124+
icon: 'flowbite:eye-solid',
125+
url: '/resource/aparts', // URL to redirect to
126+
showIn: {
127+
list: true,
128+
showButton: true,
129+
showThreeDotsMenu: true,
130+
}
131+
}
132+
```
133+
134+
The URL can be:
135+
- A relative path within your admin panel (starting with '/')
136+
- An absolute URL (starting with 'http://' or 'https://')
137+
138+
To open the URL in a new tab, add `?target=_blank` to the URL:
139+
140+
```ts
141+
{
142+
name: 'View on Google',
143+
icon: 'flowbite:external-link-solid',
144+
url: 'https://google.com/search?q=apartment&target=_blank',
145+
showIn: {
146+
list: true,
147+
showButton: true
148+
}
149+
}
150+
```
151+
152+
> ☝️ Note: You cannot specify both `action` and `url` for the same action - only one should be used.

adminforth/documentation/docs/tutorial/03-Customization/14-afcl.md renamed to adminforth/documentation/docs/tutorial/03-Customization/15-afcl.md

File renamed without changes.

adminforth/documentation/docs/tutorial/03-Customization/15-websocket.md renamed to adminforth/documentation/docs/tutorial/03-Customization/16-websocket.md

File renamed without changes.

adminforth/modules/configValidator.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,17 @@ export default class ConfigValidator implements IConfigValidator {
373373
if (!action.id) {
374374
action.id = md5hash(action.name);
375375
}
376+
if (!action.showIn) {
377+
action.showIn = {
378+
list: true,
379+
showButton: false,
380+
showThreeDotsMenu: false,
381+
}
382+
} else {
383+
action.showIn.list = action.showIn.list ?? true;
384+
action.showIn.showButton = action.showIn.showButton ?? false;
385+
action.showIn.showThreeDotsMenu = action.showIn.showThreeDotsMenu ?? false;
386+
}
376387
});
377388

378389
return actions;

0 commit comments

Comments
 (0)