Skip to content
Merged

Next #569

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
2df2b31
fix: update documentation to reflect changes in API file for dashboar…
kulikp1 Apr 16, 2026
460bbea
feat: add debug field to turns model and integrate TurnDebugShow comp…
NoOne7135 Apr 17, 2026
bcd8c31
Merge branch 'next' of github.com:devforth/adminforth into next
NoOne7135 Apr 17, 2026
c64f763
fix: add missing toolCallId property to DebugToolCall type
NoOne7135 Apr 17, 2026
419b628
refactor: remove unused icon imports and skeleton button definitions …
kulikp1 Apr 17, 2026
8f7432e
Merge branch 'next' of github.com:devforth/adminforth into next
kulikp1 Apr 17, 2026
e44fc55
Merge pull request #562 from devforth/feature/AdminForth/1438/this-is…
SerVitasik Apr 17, 2026
d7f1dd8
feat: enhance TurnDebugShow component with collapsible details and co…
NoOne7135 Apr 17, 2026
e7295c4
Merge branch 'next' of github.com:devforth/adminforth into next
NoOne7135 Apr 17, 2026
95af0a2
refactor: simplify return statement in AdminForthRestAPI class
ivictbor Apr 18, 2026
865d64f
feat: update resource handling to exclude backend-only metadata and e…
ivictbor Apr 18, 2026
07f5c64
fix: dont mutate filters (fixes bug with get_resource_data on sqlite …
ivictbor Apr 18, 2026
a113dec
fix: don't run tests over HTTP, run natively without spawning HTTP se…
ivictbor Apr 18, 2026
a07c6e5
test: add unit tests for get_resource_data datetime formatting in cal…
ivictbor Apr 19, 2026
fff01f1
fix: update model version to gpt-5.4-mini in AdminForthAgent configur…
ivictbor Apr 19, 2026
77c8516
fix: add CompletionTool type export to CompletionAdapter
ivictbor Apr 19, 2026
1a055f0
fix: update carsResourseTemplate to use dynamic labels based on data …
ivictbor Apr 19, 2026
5ca0af3
feat: add Agent Plugin documentation and image assets
ivictbor Apr 19, 2026
7043de0
dev-demo: update "update_adminforth_plugins" script to update peer de…
yaroslav8765 Apr 20, 2026
43bd5a2
Merge branch 'next' of github.com:devforth/adminforth into next
yaroslav8765 Apr 20, 2026
8d4d9ef
fix: correct file path for API example in page injections documentation
kulikp1 Apr 20, 2026
513e9ca
dev-demo: update carsResources secret_fields visibility
yaroslav8765 Apr 20, 2026
290b93a
Merge pull request #567 from devforth/feature/AdminForth/1445/update-…
SerVitasik Apr 20, 2026
571590d
fix: update installation command for agent plugin to use correct pack…
ivictbor Apr 20, 2026
e46cd06
docs: correct import of the agent plugin in docs
yaroslav8765 Apr 20, 2026
9e5af25
feat: add cached prompt tokens display and calculation in debug tool
NoOne7135 Apr 20, 2026
8c268c1
fix: correct syntax for component binding in ThreeDotsMenu
yaroslav8765 Apr 20, 2026
18c95c4
Merge branch 'next' of github.com:devforth/adminforth into next
yaroslav8765 Apr 20, 2026
ddcedc5
test: add unit tests for adminforth-agent skills registry
ivictbor Apr 20, 2026
1a72c03
feat: update TurnDebugShow to display token counts and add ForeignInl…
NoOne7135 Apr 20, 2026
1177cbc
Merge branch 'next' of github.com:devforth/adminforth into next
NoOne7135 Apr 20, 2026
649abb4
dev-demo: update dev-demo setup script not to overwrite .env file
yaroslav8765 Apr 20, 2026
49646d4
Merge branch 'next' of github.com:devforth/adminforth into next
yaroslav8765 Apr 20, 2026
e9e6baa
fix: update header icons size and grouping
yaroslav8765 Apr 20, 2026
ccbdf30
dev-demo: fix dev-demo mongo many2many resource declaration
yaroslav8765 Apr 20, 2026
7877397
docs: enhance agent plugin to support multiple modes for response gen…
NoOne7135 Apr 20, 2026
bd3f3d8
Merge branch 'next' of github.com:devforth/adminforth into next
NoOne7135 Apr 20, 2026
bafb5b0
feat: implement autologin functionality and refactor redirect logic
ivictbor Apr 20, 2026
e66a36b
feat: enhance demo iframe and update layout styles for better respons…
ivictbor Apr 20, 2026
060d4d2
feat: add sessions and turns resources with superadmin access control
ivictbor Apr 20, 2026
a37a845
Remove unused file 'undefined' from the live-demo application
ivictbor Apr 20, 2026
729e8d9
Merge branch 'main' of github.com:devforth/adminforth into next
yaroslav8765 Apr 21, 2026
67fe332
Merge branch 'next' of github.com:devforth/adminforth into next
yaroslav8765 Apr 21, 2026
d32e755
chore: return package-lock to the live-demo app
yaroslav8765 Apr 21, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ plugins/*
!plugins/README.md
adapters/*
!adapters/README.md
background-jobs-dbs
background-jobs-dbs
tests/jest_tests/db/
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

[![Ask AI](http://tluma.ai/badge)](http://tluma.ai/ask-ai/devforth/adminforth)

* [Try live demo](https://demo.adminforth.dev/) (Read-only mode)
* [Try live demo](https://demo.adminforth.dev/)

* [Hello world in 5 minutes](https://adminforth.dev/docs/tutorial/gettingStarted) with AdminForth

Expand Down
155 changes: 102 additions & 53 deletions adminforth/dataConnectors/baseConnector.ts

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion adminforth/dataConnectors/clickhouse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -498,14 +498,17 @@ class ClickhouseConnector extends AdminForthBaseConnector implements IAdminForth
filters: IAdminForthAndOrFilter;
}): Promise<number> {
const tableName = resource.table;
let normalizedFilters = filters;

// validate and normalize in case this method is called from dataAPI
if (filters) {
const filterValidation = this.validateAndNormalizeFilters(filters, resource);
if (!filterValidation.ok) {
throw new Error(filterValidation.error);
}
normalizedFilters = filterValidation.normalizedFilters as IAdminForthAndOrFilter;
}
const { where, params } = this.whereClause(resource, filters);
const { where, params } = this.whereClause(resource, normalizedFilters);

const countQ = await this.client.query({
query: `SELECT COUNT(*) as count FROM ${tableName} ${where}`,
Expand Down
5 changes: 4 additions & 1 deletion adminforth/dataConnectors/mongo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -340,15 +340,18 @@ class MongoConnector extends AdminForthBaseConnector implements IAdminForthDataS
resource: AdminForthResource,
filters: IAdminForthAndOrFilter,
}): Promise<number> {
let normalizedFilters = filters;

if (filters) {
// validate and normalize in case this method is called from dataAPI
const filterValidation = this.validateAndNormalizeFilters(filters, resource);
if (!filterValidation.ok) {
throw new Error(filterValidation.error);
}
normalizedFilters = filterValidation.normalizedFilters as IAdminForthAndOrFilter;
}
const collection = this.client.db().collection(resource.table);
const query = filters.subFilters.length ? this.getFilterQuery(resource, filters) : {};
const query = normalizedFilters.subFilters.length ? this.getFilterQuery(resource, normalizedFilters) : {};
return await collection.countDocuments(query);
}

Expand Down
5 changes: 4 additions & 1 deletion adminforth/dataConnectors/mysql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -365,14 +365,17 @@ class MysqlConnector extends AdminForthBaseConnector implements IAdminForthDataS

async getCount({ resource, filters }: { resource: AdminForthResource; filters: IAdminForthAndOrFilter; }): Promise<number> {
const tableName = resource.table;
let normalizedFilters = filters;

// validate and normalize in case this method is called from dataAPI
if (filters) {
const filterValidation = this.validateAndNormalizeFilters(filters, resource);
if (!filterValidation.ok) {
throw new Error(filterValidation.error);
}
normalizedFilters = filterValidation.normalizedFilters as IAdminForthAndOrFilter;
}
const { sql: where, values: filterValues } = this.whereClauseAndValues(filters);
const { sql: where, values: filterValues } = this.whereClauseAndValues(normalizedFilters);
const q = `SELECT COUNT(*) FROM ${tableName} ${where}`;
dbLogger.trace(`🪲📜 MySQL Q: ${q} values: ${JSON.stringify(filterValues)}`);
const [results] = await this.client.execute(q, filterValues);
Expand Down
5 changes: 4 additions & 1 deletion adminforth/dataConnectors/postgres.ts
Original file line number Diff line number Diff line change
Expand Up @@ -396,14 +396,17 @@ class PostgresConnector extends AdminForthBaseConnector implements IAdminForthDa

async getCount({ resource, filters }: { resource: AdminForthResource; filters: IAdminForthAndOrFilter; }): Promise<number> {
const tableName = resource.table;
let normalizedFilters = filters;

// validate and normalize in case this method is called from dataAPI
if (filters) {
const filterValidation = this.validateAndNormalizeFilters(filters, resource);
if (!filterValidation.ok) {
throw new Error(filterValidation.error);
}
normalizedFilters = filterValidation.normalizedFilters as IAdminForthAndOrFilter;
}
const { sql: where, values: filterValues } = this.whereClauseAndValues(resource, filters);
const { sql: where, values: filterValues } = this.whereClauseAndValues(resource, normalizedFilters);
const q = `SELECT COUNT(*) FROM "${tableName}" ${where}`;
dbLogger.trace(`🪲📜 PG Q: ${q}, values: ${JSON.stringify(filterValues)}`);
const stmt = await this.client.query(q, filterValues);
Expand Down
7 changes: 5 additions & 2 deletions adminforth/dataConnectors/sqlite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -326,16 +326,19 @@ class SQLiteConnector extends AdminForthBaseConnector implements IAdminForthData
}

async getCount({ resource, filters }) {
let normalizedFilters = filters;

if (filters) {
// validate and normalize in case this method is called from dataAPI
const filterValidation = this.validateAndNormalizeFilters(filters, resource);
if (!filterValidation.ok) {
throw new Error(filterValidation.error);
}
normalizedFilters = filterValidation.normalizedFilters as IAdminForthAndOrFilter;
}
const tableName = resource.table;
const where = this.whereClause(filters);
const filterValues = this.getFilterParams(filters);
const where = this.whereClause(normalizedFilters);
const filterValues = this.getFilterParams(normalizedFilters);
const q = `SELECT COUNT(*) FROM ${tableName} ${where}`;
dbLogger.trace(`🪲📜 SQLITE Q: ${q}, params: ${JSON.stringify(filterValues)}`);
const totalStmt = this.client.prepare(q);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -317,9 +317,9 @@ Now we have to define this endpoint in the backend to make our page work:



Open `index.ts` file and add the following code *BEFORE* `admin.express.serve(` !
Open `api.ts` file and add the following code *BEFORE* `admin.express.authorize` !

```ts title="/index.ts"
```ts title="/api.ts"

import type { IAdminUserExpressRequest } from 'adminforth';
import express from 'express';
Expand Down Expand Up @@ -429,11 +429,6 @@ app.get(`${ADMIN_BASE_URL}/api/dashboard/`,
)
)
);

// serve after you added all api
admin.express.serve(app)
admin.discoverDatabases();

```

Install and import Zod before using this pattern: `pnpm add zod` or `npm install zod`, then `import * as z from 'zod';`. `admin.express.withSchema(...)` will convert the Zod schema to OpenAPI for you.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ Now create file `ApartsPie.vue` in the `custom` folder of your project:

Also we have to add an Api to get percentages:

```ts title="./index.ts"
```ts title="/api.ts"
import type { IAdminUserExpressRequest } from 'adminforth';
import express from 'express';
import * as z from 'zod';
Expand Down Expand Up @@ -152,10 +152,6 @@ import * as z from 'zod';
)
)
);

// serve after you added all api
admin.discoverDatabases();
admin.express.serve(app)
```

Install and import Zod before using this pattern: `pnpm add zod` or `npm install zod`, then `import * as z from 'zod';`. `admin.express.withSchema(...)` will convert the Zod schema to OpenAPI for you.
Expand Down
Loading