Skip to content

Commit 7dc653c

Browse files
committed
Merge branch 'main' of github.com:devforth/adminforth
2 parents b4b2870 + 0b5660b commit 7dc653c

20 files changed

Lines changed: 916 additions & 145 deletions

File tree

README.md

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,32 +37,43 @@ Why AdminForth:
3737

3838
## Project initialisation
3939

40-
```
41-
mkdir myadmin && cd myadmin
40+
To create an AdminForth project, run:
41+
42+
```bash
4243
npx adminforth create-app
4344
```
4445

45-
## Previews
46+
During the interactive initialization process, AdminForth will ask you to provide a local database URL.
4647

47-
<a href="https://adminforth.dev/docs/tutorial/Customization/customPages">Custom Dashboard</a>
48-
<br/>
49-
<img src="https://github.com/user-attachments/assets/aa899196-f7f3-4582-839c-2267f2e9e197" alt="AdminForth Dashboard demo" width="80%" />
48+
### Integrating AdminForth into your existing application
5049

51-
<a href="https://adminforth.dev/docs/tutorial/Plugins/chat-gpt">Text completion plugin (Copilot-style) using LLMs</a>
52-
<br/>
50+
If you want to build an admin panel for an existing project that already has a database with tables, you can provide the connection URL to your existing development database, such as a local or deployed one.
5351

54-
<img src="https://github.com/user-attachments/assets/cfa17cbd-3a53-4725-ab46-53c7c7666028" alt="AdminForth ChatGPT demo" width="80%" />
52+
After that, you may want to generate AdminForth resource files from your existing database tables:
5553

56-
<a href="https://adminforth.dev/docs/tutorial/Plugins/upload/#image-generation">Image Generation using image generation models</a>
57-
<br/>
58-
<img src="https://github.com/user-attachments/assets/b923e044-7e29-46ff-ab91-eeca5eee2b0a" alt="AdminForth DALE-E image generator demo" width="80%">
54+
```bash
55+
npx adminforth resource
56+
```
57+
58+
Resource files are needed for AdminForth to “know” about your tables and define how to work with them.
59+
60+
Use the command above every time you add new tables or change their schema.
61+
62+
### Starting from scratch
63+
64+
If you do not have a database yet, start an empty local database, for example PostgreSQL in Docker, and provide its URL to the AdminForth CLI.
65+
66+
If the adminforth CLI does not detect any tables, it will suggest adding Prisma as a migration tool. Prisma is not related to AdminForth, but it is one of the most convenient migration tools.
67+
68+
Please follow [getting started](https://adminforth.dev/docs/tutorial/gettingStarted/).
5969

70+
# For AdminForth developers
6071

61-
# For developers
72+
> Follow this section only if you want to make changes to the AdminForth framework or develop a plugin.
6273
63-
The most convenient way to add new features or fixes is using `dev-demo`. It imports the source code of the repository and plugins so you can edit them and see changes on the fly.
74+
The most convenient way to add new features or fixes is to use `dev-demo`. It imports the repository source code and plugins, so you can edit them and see changes on the fly.
6475

65-
# Requirements
76+
## Requirements
6677

6778
- **Node.js 20**
6879
- **Docker**

adminforth/dataConnectors/sqlite.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ class SQLiteConnector extends AdminForthBaseConnector implements IAdminForthData
101101
const [precision, scale] = baseType.match(/\d+/g);
102102
field.precision = parseInt(precision);
103103
field.scale = parseInt(scale);
104+
} else if (baseType == 'json' || baseType == 'jsonb') {
105+
field.type = AdminForthDataTypes.JSON;
106+
field._underlineType = baseType;
104107
} else if (baseType === 'decimal') {
105108
field.type = AdminForthDataTypes.DECIMAL;
106109
field._underlineType = 'decimal';

adminforth/documentation/blog/2025-11-04-k3s-ec2-deployment/index.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -729,13 +729,14 @@ sed -i 's/certificate-authority-data:.*/insecure-skip-tls-verify: true/g' kubeco
729729
export KUBECONFIG=$(pwd)/kubeconfig.yaml
730730
731731
cd helm
732-
export APP_NAMESPACE="myadmin"
733-
export IMAGE_FULL_TAG="$${ACCOUNT_ID}.dkr.ecr.$${REGION}.amazonaws.com/myadmink3s:$${TAG}"
732+
export APP_NAMESPACE="myadmin" # <<< SET YOUR APP NAMESPACE HERE
733+
export IMAGE_FULL_TAG="$${ACCOUNT_ID}.dkr.ecr.$${REGION}.amazonaws.com/myadmink3s:$${TAG}" # Change 'myadmink3s' to your app name in 'helmfile.yaml' & 'Chart.yaml' files as well
734734
helmfile apply
735735
cd ..
736736
737737
echo "Deployment complete!"
738738
```
739+
You need to change the values of `APP_NAMESPACE` and `IMAGE_FULL_TAG` in the `deploy/deploy.sh` script to match your application name and image tag. Note that `IMAGE_FULL_TAG` is constructed dynamically from the Terraform outputs and the tag, so you only need to change `APP_NAMESPACE`.
739740

740741
Don't forget to make the script executable:
741742

adminforth/documentation/docs/tutorial/03-Customization/10-menuConfiguration.md

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,3 +304,129 @@ menu: [
304304

305305
```
306306
> 👆 Please note start internal URLs with a leading / to ensure correct routing.
307+
308+
309+
## Adding menu items from plugins
310+
311+
Plugins can add top-level menu items without mutating the user-defined `config.menu`. This keeps the application menu owned by the app configuration, while plugins can contribute their own entries.
312+
313+
Use `registerMenuContribution` from a plugin's `modifyResourceConfig`:
314+
315+
```ts title='./plugins/adminforth-dashboard/index.ts'
316+
async modifyResourceConfig(adminforth, resourceConfig) {
317+
super.modifyResourceConfig(adminforth, resourceConfig);
318+
319+
adminforth.registerMenuContribution({
320+
item: {
321+
itemId: 'dashboard',
322+
type: 'page',
323+
label: 'Dashboard',
324+
icon: 'flowbite:chart-pie-solid',
325+
path: '/dashboard',
326+
component: this.componentPath('Dashboard.vue'),
327+
},
328+
placement: { before: { resourceId: 'adminuser' } },
329+
});
330+
}
331+
```
332+
333+
Supported placements:
334+
335+
```ts
336+
adminforth.registerMenuContribution({
337+
item: {
338+
itemId: 'dashboard',
339+
type: 'page',
340+
label: 'Dashboard',
341+
path: '/dashboard',
342+
component: this.componentPath('Dashboard.vue'),
343+
},
344+
placement: { position: 'first' },
345+
});
346+
347+
adminforth.registerMenuContribution({
348+
item: {
349+
itemId: 'reports',
350+
type: 'page',
351+
label: 'Reports',
352+
path: '/reports',
353+
component: this.componentPath('Reports.vue'),
354+
},
355+
placement: { after: { resourceId: 'orders' } },
356+
});
357+
```
358+
359+
`placement` can be:
360+
361+
- `{ position: 'first' }`
362+
- `{ position: 'last' }`
363+
- `{ before: 'usersMenuItemId' }`
364+
- `{ after: 'usersMenuItemId' }`
365+
- `{ before: { itemId: 'usersMenuItemId' } }`
366+
- `{ after: { resourceId: 'adminuser' } }`
367+
- `{ before: { path: '/reports' } }`
368+
369+
If placement is omitted, or if the target item is not found, AdminForth appends the contributed item to the end of the top-level menu.
370+
371+
Plugin menu contributions are additive only:
372+
373+
- user-defined `config.menu` is not changed
374+
- plugins cannot remove or edit existing menu items through this API
375+
- contributed `itemId` must not duplicate an existing top-level menu item
376+
- this first version inserts only top-level menu items
377+
378+
### Dynamic menu items from plugin state
379+
380+
If a plugin needs to add menu items at runtime, for example after a user clicks a button and creates a new dashboard, register a menu contribution provider. AdminForth calls providers every time it fetches the menu.
381+
382+
```ts title='./plugins/adminforth-dashboard/index.ts'
383+
async modifyResourceConfig(adminforth, resourceConfig) {
384+
super.modifyResourceConfig(adminforth, resourceConfig);
385+
386+
adminforth.registerMenuContributionProvider(async ({ adminUser, adminforth }) => {
387+
const dashboards = await adminforth.resource('dashboards').list();
388+
389+
return [
390+
{
391+
item: {
392+
itemId: 'dashboardsMenu',
393+
type: 'group',
394+
label: 'Dashboards',
395+
icon: 'flowbite:chart-pie-solid',
396+
children: dashboards.map((dashboard) => ({
397+
itemId: `dashboard-${dashboard.id}`,
398+
type: 'page',
399+
label: dashboard.name,
400+
path: `/dashboards/${dashboard.id}`,
401+
})),
402+
},
403+
placement: { position: 'first' },
404+
},
405+
];
406+
});
407+
}
408+
```
409+
410+
After the plugin changes the state used by the provider, call `refreshMenu` on the backend:
411+
412+
```ts
413+
await adminforth.resource('dashboards').create({
414+
name: 'Sales',
415+
});
416+
417+
await adminforth.refreshMenu(adminUser);
418+
```
419+
420+
AdminForth sends a websocket event to the current user, and the frontend refetches the menu without a page reload.
421+
422+
Frontend components can also refresh the menu directly:
423+
424+
```ts
425+
import { useAdminforth } from '@/adminforth';
426+
427+
const { menu } = useAdminforth();
428+
429+
await menu.refresh();
430+
```
431+
432+
Dynamic menu items should point to routes that are already available in the SPA. If a provider returns a brand-new custom `component` path that was not known during AdminForth build, the menu item can appear, but the route will not be registered until the app is rebuilt.

adminforth/documentation/docs/tutorial/05-Adapters/09-chat-surface-adapters.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title: Telegram Chat Surface Adapter (WIP)
2+
title: Telegram Chat Surface Adapter
33
description: "Reference page for AdminForth Agent chat surface adapters, including Telegram bot setup and webhook configuration."
44
slug: /tutorial/Adapters/chat-surface-adapter-telegram
55
sidebar_position: 8

0 commit comments

Comments
 (0)