From 6fa89c6882e992be8601cf7de3547c88d4d5069a Mon Sep 17 00:00:00 2001 From: Vitalii Kulyk Date: Fri, 17 Apr 2026 16:25:20 +0300 Subject: [PATCH 1/6] merge migrations --- Taskfile.yml | 27 +++++++++++++++ .../migration.sql | 2 ++ .../20260415080036_add_cars/migration.sql | 33 +++++++++++++++++++ dev-demo/resources/adminuser.ts | 26 --------------- 4 files changed, 62 insertions(+), 26 deletions(-) create mode 100644 Taskfile.yml create mode 100644 dev-demo/migrations/prisma/sqlite/migrations/20260401085719_add_listed_to_translations/migration.sql create mode 100644 dev-demo/migrations/prisma/sqlite/migrations/20260415080036_add_cars/migration.sql diff --git a/Taskfile.yml b/Taskfile.yml new file mode 100644 index 000000000..7b674ae69 --- /dev/null +++ b/Taskfile.yml @@ -0,0 +1,27 @@ +version: '3' + +tasks: + update-adminforth-version: + desc: "Update adminforth peer/dev dependency version in all plugins and adapters" + vars: + VERSION: '{{.VERSION | default ""}}' + preconditions: + - sh: '[ -n "{{.VERSION}}" ]' + msg: "VERSION is required. Run: task update-adminforth-version VERSION=1.2.3" + cmds: + - | + for dir in plugins/*/ adapters/*/; do + pkg="$dir/package.json" + [ -f "$pkg" ] || continue + node -e " + const fs = require('fs'); + const p = JSON.parse(fs.readFileSync('$pkg')); + let changed = false; + if (p.peerDependencies?.adminforth) { p.peerDependencies.adminforth = '^{{.VERSION}}'; changed = true; } + if (p.devDependencies?.adminforth) { p.devDependencies.adminforth = '^{{.VERSION}}'; changed = true; } + if (changed) { + fs.writeFileSync('$pkg', JSON.stringify(p, null, 2) + '\n'); + console.log('updated: $pkg'); + } + " + done diff --git a/dev-demo/migrations/prisma/sqlite/migrations/20260401085719_add_listed_to_translations/migration.sql b/dev-demo/migrations/prisma/sqlite/migrations/20260401085719_add_listed_to_translations/migration.sql new file mode 100644 index 000000000..4f1ebf190 --- /dev/null +++ b/dev-demo/migrations/prisma/sqlite/migrations/20260401085719_add_listed_to_translations/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "translations" ADD COLUMN "listed" BOOLEAN; diff --git a/dev-demo/migrations/prisma/sqlite/migrations/20260415080036_add_cars/migration.sql b/dev-demo/migrations/prisma/sqlite/migrations/20260415080036_add_cars/migration.sql new file mode 100644 index 000000000..03d0b5611 --- /dev/null +++ b/dev-demo/migrations/prisma/sqlite/migrations/20260415080036_add_cars/migration.sql @@ -0,0 +1,33 @@ +/* + Warnings: + + - You are about to drop the column `listed` on the `translations` table. All the data in the column will be lost. + +*/ +-- AlterTable +ALTER TABLE "adminuser" ADD COLUMN "cars" TEXT; + +-- RedefineTables +PRAGMA defer_foreign_keys=ON; +PRAGMA foreign_keys=OFF; +CREATE TABLE "new_translations" ( + "id" TEXT NOT NULL PRIMARY KEY, + "en_string" TEXT NOT NULL, + "created_at" DATETIME NOT NULL, + "uk_string" TEXT, + "ja_string" TEXT, + "fr_string" TEXT, + "es_string" TEXT, + "ptBR_string" TEXT, + "category" TEXT NOT NULL, + "source" TEXT, + "completedLangs" TEXT +); +INSERT INTO "new_translations" ("category", "completedLangs", "created_at", "en_string", "es_string", "fr_string", "id", "ja_string", "ptBR_string", "source", "uk_string") SELECT "category", "completedLangs", "created_at", "en_string", "es_string", "fr_string", "id", "ja_string", "ptBR_string", "source", "uk_string" FROM "translations"; +DROP TABLE "translations"; +ALTER TABLE "new_translations" RENAME TO "translations"; +CREATE INDEX "translations_en_string_category_idx" ON "translations"("en_string", "category"); +CREATE INDEX "translations_category_idx" ON "translations"("category"); +CREATE INDEX "translations_completedLangs_idx" ON "translations"("completedLangs"); +PRAGMA foreign_keys=ON; +PRAGMA defer_foreign_keys=OFF; diff --git a/dev-demo/resources/adminuser.ts b/dev-demo/resources/adminuser.ts index 3c0c428e0..d458da7df 100644 --- a/dev-demo/resources/adminuser.ts +++ b/dev-demo/resources/adminuser.ts @@ -10,7 +10,6 @@ import AdminForthAdapterGoogleOauth2 from '../../adapters/adminforth-oauth-adapt import OpenSignupPlugin from '../../plugins/adminforth-open-signup/index.js'; import OAuthPlugin from '../../plugins/adminforth-oauth/index.js'; import KeyValueAdapterRam from '../../adapters/adminforth-key-value-adapter-ram/index.js'; -import AdminForthAgent from '../../plugins/adminforth-agent/index.js'; import CompletionAdapterOpenAIChatGPT from '../../adapters/adminforth-completion-adapter-open-ai-chat-gpt/index.js'; async function allowedForSuperAdmin({ adminUser }: { adminUser: AdminUser }): Promise { @@ -192,31 +191,6 @@ export default { }, }, }), - new AdminForthAgent({ - completionAdapter: new CompletionAdapterOpenAIChatGPT({ - openAiApiKey: process.env.OPENAI_API_KEY as string, - model: 'gpt-5-mini', - }), - maxTokens: 10000, - reasoning: 'none', - sessionResource: { - resourceId: 'sessions', - idField: 'id', - titleField: 'title', - turnsField: 'turns', - askerIdField: 'asker_id', - createdAtField: 'created_at', - }, - turnResource: { - resourceId: 'turns', - idField: 'id', - sessionIdField: 'session_id', - createdAtField: 'created_at', - promptField: 'prompt', - responseField: 'response', - debugField: 'dubbug', - }, - }), ], hooks: { create: { From c0d55a10be9ae4900bfe81e6ad6d89c88b21a376 Mon Sep 17 00:00:00 2001 From: Vitalii Kulyk Date: Mon, 20 Apr 2026 11:53:02 +0300 Subject: [PATCH 2/6] feat: normalize allowed action handling and update related types --- adminforth/modules/configValidator.ts | 18 +++++++++----- adminforth/modules/restApi.ts | 34 +++++++++++++++++++-------- adminforth/spa/src/utils/utils.ts | 2 +- adminforth/spa/src/views/ListView.vue | 2 +- adminforth/types/Back.ts | 4 ++-- adminforth/types/Common.ts | 2 +- 6 files changed, 41 insertions(+), 21 deletions(-) diff --git a/adminforth/modules/configValidator.ts b/adminforth/modules/configValidator.ts index f283013c6..5e8637fa2 100644 --- a/adminforth/modules/configValidator.ts +++ b/adminforth/modules/configValidator.ts @@ -1,8 +1,9 @@ -import { - AdminForthConfig, - AdminForthResource, - IAdminForth, IConfigValidator, +import { + AdminForthConfig, + AdminForthResource, + IAdminForth, IConfigValidator, AdminForthBulkAction, + AdminForthActionInput, AdminForthInputConfig, AdminForthConfigCustomization, AdminForthResourceInput, @@ -388,7 +389,7 @@ export default class ConfigValidator implements IConfigValidator { }); } - validateAndNormalizeCustomActions(resInput: AdminForthResourceInput, res: Partial, errors: string[]): any[] { + validateAndNormalizeCustomActions(resInput: AdminForthResourceInput, res: Partial, errors: string[]): AdminForthActionInput[] { if (!resInput.options?.actions) { return []; } @@ -430,13 +431,18 @@ export default class ConfigValidator implements IConfigValidator { action.showIn.showThreeDotsMenu = action.showIn.showThreeDotsMenu ?? false; } + if (typeof action.allowed === 'boolean') { + const val = action.allowed; + action.allowed = () => val; + } + const shownInNonBulk = action.showIn.list || action.showIn.listThreeDotsMenu || action.showIn.showButton || action.showIn.showThreeDotsMenu; if (shownInNonBulk && !action.action && !action.url) { errors.push(`Resource "${res.resourceId}" action "${action.name}" has showIn enabled for non-bulk locations (list, listThreeDotsMenu, showButton, showThreeDotsMenu) but has no "action" or "url" handler. Either add an "action" handler or set those showIn flags to false.`); } }); - return actions; + return actions as AdminForthActionInput[]; } validateAndNormalizeResources(errors: string[], warnings: string[]): AdminForthResource[] { diff --git a/adminforth/modules/restApi.ts b/adminforth/modules/restApi.ts index 1b994337b..5bc391e69 100644 --- a/adminforth/modules/restApi.ts +++ b/adminforth/modules/restApi.ts @@ -23,9 +23,9 @@ import { afLogger } from "./logger.js"; import { ADMINFORTH_VERSION, listify, md5hash, getLoginPromptHTML, hookResponseError } from './utils.js'; import AdminForthAuth from "../auth.js"; -import { ActionCheckSource, AdminForthConfigMenuItem, AdminForthDataTypes, AdminForthFilterOperators, AdminForthResourceColumnInputCommon, AdminForthResourceFrontend, AdminForthResourcePages, +import { ActionCheckSource, AdminForthActionFront, AdminForthConfigMenuItem, AdminForthDataTypes, AdminForthFilterOperators, AdminForthResourceColumnInputCommon, AdminForthResourceFrontend, AdminForthResourcePages, AdminForthSortDirections, - AdminUser, AllowedActionsEnum, AllowedActionsResolved, + AdminUser, AllowedActionsEnum, AllowedActionsResolved, AnnouncementBadgeResponse, GetBaseConfigResponse, ShowInResolved} from "../types/Common.js"; @@ -1079,6 +1079,22 @@ export default class AdminForthRestAPI implements IAdminForthRestAPI { }) ); + const allowedCustomActions = []; + if (resource.options.actions) { + await Promise.all( + resource.options.actions.map(async (action) => { + if (typeof action.allowed === 'function') { + const res = await action.allowed({ adminUser, standardAllowedActions: allowedActions }); + if (res) { + allowedCustomActions.push(action); + } + } else { + allowedCustomActions.push(action); + } + }) + ); + } + // translate const translateRoutines: Record> = {}; translateRoutines.resLabel = tr(resource.label, `resource.${resource.resourceId}`); @@ -1191,12 +1207,10 @@ export default class AdminForthRestAPI implements IAdminForthRestAPI { confirm: action.confirm ? translated[`bulkActionConfirm${i}`] : action.confirm, }) ), - actions: resource.options.actions?.map((action) => ({ - ...action, - id: action.id!, - hasBulkHandler: !!action.bulkHandler, - bulkHandler: undefined, - })), + actions: allowedCustomActions.map(({ bulkHandler, allowed, action: actionFn, ...rest }) => ({ + ...rest, + ...(bulkHandler && { bulkHandler: true }), + })) as AdminForthActionFront[], allowedActions, } } @@ -2096,7 +2110,7 @@ export default class AdminForthRestAPI implements IAdminForthRestAPI { if (!action) { return { error: await tr(`Action {actionId} not found`, 'errors', { actionId }) }; } - if (action.allowed) { + if (typeof action.allowed === 'function') { const execAllowed = await action.allowed({ adminUser, standardAllowedActions: allowedActions }); if (!execAllowed) { return { error: await tr(`Action "{actionId}" not allowed`, 'errors', { actionId: action.name }) }; @@ -2148,7 +2162,7 @@ export default class AdminForthRestAPI implements IAdminForthRestAPI { if (!action.bulkHandler) { return { error: await tr(`Action "{actionId}" has no bulkHandler`, 'errors', { actionId }) }; } - if (action.allowed) { + if (typeof action.allowed === 'function') { const execAllowed = await action.allowed({ adminUser, standardAllowedActions: allowedActions }); if (!execAllowed) { return { error: await tr(`Action "{actionId}" not allowed`, 'errors', { actionId: action.name }) }; diff --git a/adminforth/spa/src/utils/utils.ts b/adminforth/spa/src/utils/utils.ts index f77d8aa3f..7129f114d 100644 --- a/adminforth/spa/src/utils/utils.ts +++ b/adminforth/spa/src/utils/utils.ts @@ -803,7 +803,7 @@ export async function executeCustomBulkAction({ try { const action = resource?.options?.actions?.find((a: any) => a.id === actionId) as AdminForthActionFront | undefined; - if (action?.hasBulkHandler && action?.showIn?.bulkButton) { + if (action?.bulkHandler && action?.showIn?.bulkButton) { const result = await callAdminForthApi({ path: '/start_custom_bulk_action', method: 'POST', diff --git a/adminforth/spa/src/views/ListView.vue b/adminforth/spa/src/views/ListView.vue index 266a7b25f..0c2d82d07 100644 --- a/adminforth/spa/src/views/ListView.vue +++ b/adminforth/spa/src/views/ListView.vue @@ -344,7 +344,7 @@ async function startCustomBulkActionInner(actionId: string | number) { const successResults = results.filter(r => r?.successMessage); if (successResults.length > 0) { alert({ - message: action?.bulkSuccessMessage ? action.bulkSuccessMessage : action?.hasBulkHandler ? successResults[0].successMessage : `${successResults.length} out of ${results.length} items processed successfully`, + message: action?.bulkSuccessMessage ? action.bulkSuccessMessage : action?.bulkHandler ? successResults[0].successMessage : `${successResults.length} out of ${results.length} items processed successfully`, variant: 'success' }); } diff --git a/adminforth/types/Back.ts b/adminforth/types/Back.ts index f51b101a7..c9331bea8 100644 --- a/adminforth/types/Back.ts +++ b/adminforth/types/Back.ts @@ -1389,10 +1389,10 @@ export interface AdminForthActionInput { showThreeDotsMenu?: boolean, bulkButton?: boolean, }; - allowed?: (params: { + allowed?: boolean | ((params: { adminUser: AdminUser; standardAllowedActions: AllowedActions; - }) => boolean; + }) => boolean | Promise); url?: string; bulkHandler?: (params: { adminforth: IAdminForth; diff --git a/adminforth/types/Common.ts b/adminforth/types/Common.ts index d10beb1fb..bdd503799 100644 --- a/adminforth/types/Common.ts +++ b/adminforth/types/Common.ts @@ -316,7 +316,7 @@ export type FieldGroup = { export interface AdminForthActionFront extends Omit { id: string; - hasBulkHandler?: boolean; + bulkHandler?: boolean; } export interface AdminForthBulkActionFront extends Omit { From 1d85ec4d06f2c660714b06fb70f39d7cd5642443 Mon Sep 17 00:00:00 2001 From: Vitalii Kulyk Date: Mon, 20 Apr 2026 12:02:46 +0300 Subject: [PATCH 3/6] refactor: remove Taskfile and update adminuser.ts imports and structure --- Taskfile.yml | 27 --------------- dev-demo/resources/adminuser.ts | 59 +++++++++++++++++++-------------- 2 files changed, 34 insertions(+), 52 deletions(-) delete mode 100644 Taskfile.yml diff --git a/Taskfile.yml b/Taskfile.yml deleted file mode 100644 index 7b674ae69..000000000 --- a/Taskfile.yml +++ /dev/null @@ -1,27 +0,0 @@ -version: '3' - -tasks: - update-adminforth-version: - desc: "Update adminforth peer/dev dependency version in all plugins and adapters" - vars: - VERSION: '{{.VERSION | default ""}}' - preconditions: - - sh: '[ -n "{{.VERSION}}" ]' - msg: "VERSION is required. Run: task update-adminforth-version VERSION=1.2.3" - cmds: - - | - for dir in plugins/*/ adapters/*/; do - pkg="$dir/package.json" - [ -f "$pkg" ] || continue - node -e " - const fs = require('fs'); - const p = JSON.parse(fs.readFileSync('$pkg')); - let changed = false; - if (p.peerDependencies?.adminforth) { p.peerDependencies.adminforth = '^{{.VERSION}}'; changed = true; } - if (p.devDependencies?.adminforth) { p.devDependencies.adminforth = '^{{.VERSION}}'; changed = true; } - if (changed) { - fs.writeFileSync('$pkg', JSON.stringify(p, null, 2) + '\n'); - console.log('updated: $pkg'); - } - " - done diff --git a/dev-demo/resources/adminuser.ts b/dev-demo/resources/adminuser.ts index f0920d6cd..e2dfb5e89 100644 --- a/dev-demo/resources/adminuser.ts +++ b/dev-demo/resources/adminuser.ts @@ -10,6 +10,7 @@ import AdminForthAdapterGoogleOauth2 from '../../adapters/adminforth-oauth-adapt import OpenSignupPlugin from '../../plugins/adminforth-open-signup/index.js'; import OAuthPlugin from '../../plugins/adminforth-oauth/index.js'; import KeyValueAdapterRam from '../../adapters/adminforth-key-value-adapter-ram/index.js'; +import AdminForthAgent from '../../plugins/adminforth-agent/index.js'; import CompletionAdapterOpenAIChatGPT from '../../adapters/adminforth-completion-adapter-open-ai-chat-gpt/index.js'; async function allowedForSuperAdmin({ adminUser }: { adminUser: AdminUser }): Promise { @@ -95,6 +96,14 @@ export default { resourceId: 'adminuser', } }, + { + name: "cars", + type: AdminForthDataTypes.STRING, + foreignResource: { + resourceId: 'cars_sl', + searchableFields: ['model'] + } + }, { name: "avatar", type: AdminForthDataTypes.STRING, @@ -191,31 +200,31 @@ export default { }, }, }), - new AdminForthAgent({ - completionAdapter: new CompletionAdapterOpenAIChatGPT({ - openAiApiKey: process.env.OPENAI_API_KEY as string, - model: 'gpt-5.4-mini', - }), - maxTokens: 10000, - reasoning: 'none', - sessionResource: { - resourceId: 'sessions', - idField: 'id', - titleField: 'title', - turnsField: 'turns', - askerIdField: 'asker_id', - createdAtField: 'created_at', - }, - turnResource: { - resourceId: 'turns', - idField: 'id', - sessionIdField: 'session_id', - createdAtField: 'created_at', - promptField: 'prompt', - responseField: 'response', - debugField: 'dubbug', - }, - }), + // new AdminForthAgent({ + // completionAdapter: new CompletionAdapterOpenAIChatGPT({ + // openAiApiKey: process.env.OPENAI_API_KEY as string, + // model: 'gpt-5.4-mini', + // }), + // maxTokens: 10000, + // reasoning: 'none', + // sessionResource: { + // resourceId: 'sessions', + // idField: 'id', + // titleField: 'title', + // turnsField: 'turns', + // askerIdField: 'asker_id', + // createdAtField: 'created_at', + // }, + // turnResource: { + // resourceId: 'turns', + // idField: 'id', + // sessionIdField: 'session_id', + // createdAtField: 'created_at', + // promptField: 'prompt', + // responseField: 'response', + // debugField: 'dubbug', + // }, + // }), ], hooks: { create: { From 65a2103f71555400ec78e2bdf45168c286d07395 Mon Sep 17 00:00:00 2001 From: Vitalii Kulyk Date: Mon, 20 Apr 2026 12:30:51 +0300 Subject: [PATCH 4/6] feat: normalize AdminForthAgent instantiation and improve code structure --- dev-demo/resources/adminuser.ts | 50 ++++++++++++++++----------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/dev-demo/resources/adminuser.ts b/dev-demo/resources/adminuser.ts index e2dfb5e89..bbe75de87 100644 --- a/dev-demo/resources/adminuser.ts +++ b/dev-demo/resources/adminuser.ts @@ -200,31 +200,31 @@ export default { }, }, }), - // new AdminForthAgent({ - // completionAdapter: new CompletionAdapterOpenAIChatGPT({ - // openAiApiKey: process.env.OPENAI_API_KEY as string, - // model: 'gpt-5.4-mini', - // }), - // maxTokens: 10000, - // reasoning: 'none', - // sessionResource: { - // resourceId: 'sessions', - // idField: 'id', - // titleField: 'title', - // turnsField: 'turns', - // askerIdField: 'asker_id', - // createdAtField: 'created_at', - // }, - // turnResource: { - // resourceId: 'turns', - // idField: 'id', - // sessionIdField: 'session_id', - // createdAtField: 'created_at', - // promptField: 'prompt', - // responseField: 'response', - // debugField: 'dubbug', - // }, - // }), + new AdminForthAgent({ + completionAdapter: new CompletionAdapterOpenAIChatGPT({ + openAiApiKey: process.env.OPENAI_API_KEY as string, + model: 'gpt-5.4-mini', + }), + maxTokens: 10000, + reasoning: 'none', + sessionResource: { + resourceId: 'sessions', + idField: 'id', + titleField: 'title', + turnsField: 'turns', + askerIdField: 'asker_id', + createdAtField: 'created_at', + }, + turnResource: { + resourceId: 'turns', + idField: 'id', + sessionIdField: 'session_id', + createdAtField: 'created_at', + promptField: 'prompt', + responseField: 'response', + debugField: 'dubbug', + }, + }), ], hooks: { create: { From a3fe2eff1a523c8c70b0ded9ef4d785095ba91e4 Mon Sep 17 00:00:00 2001 From: Vitalii Kulyk Date: Mon, 20 Apr 2026 13:52:16 +0300 Subject: [PATCH 5/6] refactor: remove deprecated migration files and clean up adminuser resource --- .../migration.sql | 2 -- .../20260415080036_add_cars/migration.sql | 33 ------------------- dev-demo/resources/adminuser.ts | 8 ----- 3 files changed, 43 deletions(-) delete mode 100644 dev-demo/migrations/prisma/sqlite/migrations/20260401085719_add_listed_to_translations/migration.sql delete mode 100644 dev-demo/migrations/prisma/sqlite/migrations/20260415080036_add_cars/migration.sql diff --git a/dev-demo/migrations/prisma/sqlite/migrations/20260401085719_add_listed_to_translations/migration.sql b/dev-demo/migrations/prisma/sqlite/migrations/20260401085719_add_listed_to_translations/migration.sql deleted file mode 100644 index 4f1ebf190..000000000 --- a/dev-demo/migrations/prisma/sqlite/migrations/20260401085719_add_listed_to_translations/migration.sql +++ /dev/null @@ -1,2 +0,0 @@ --- AlterTable -ALTER TABLE "translations" ADD COLUMN "listed" BOOLEAN; diff --git a/dev-demo/migrations/prisma/sqlite/migrations/20260415080036_add_cars/migration.sql b/dev-demo/migrations/prisma/sqlite/migrations/20260415080036_add_cars/migration.sql deleted file mode 100644 index 03d0b5611..000000000 --- a/dev-demo/migrations/prisma/sqlite/migrations/20260415080036_add_cars/migration.sql +++ /dev/null @@ -1,33 +0,0 @@ -/* - Warnings: - - - You are about to drop the column `listed` on the `translations` table. All the data in the column will be lost. - -*/ --- AlterTable -ALTER TABLE "adminuser" ADD COLUMN "cars" TEXT; - --- RedefineTables -PRAGMA defer_foreign_keys=ON; -PRAGMA foreign_keys=OFF; -CREATE TABLE "new_translations" ( - "id" TEXT NOT NULL PRIMARY KEY, - "en_string" TEXT NOT NULL, - "created_at" DATETIME NOT NULL, - "uk_string" TEXT, - "ja_string" TEXT, - "fr_string" TEXT, - "es_string" TEXT, - "ptBR_string" TEXT, - "category" TEXT NOT NULL, - "source" TEXT, - "completedLangs" TEXT -); -INSERT INTO "new_translations" ("category", "completedLangs", "created_at", "en_string", "es_string", "fr_string", "id", "ja_string", "ptBR_string", "source", "uk_string") SELECT "category", "completedLangs", "created_at", "en_string", "es_string", "fr_string", "id", "ja_string", "ptBR_string", "source", "uk_string" FROM "translations"; -DROP TABLE "translations"; -ALTER TABLE "new_translations" RENAME TO "translations"; -CREATE INDEX "translations_en_string_category_idx" ON "translations"("en_string", "category"); -CREATE INDEX "translations_category_idx" ON "translations"("category"); -CREATE INDEX "translations_completedLangs_idx" ON "translations"("completedLangs"); -PRAGMA foreign_keys=ON; -PRAGMA defer_foreign_keys=OFF; diff --git a/dev-demo/resources/adminuser.ts b/dev-demo/resources/adminuser.ts index bbe75de87..a2e746dba 100644 --- a/dev-demo/resources/adminuser.ts +++ b/dev-demo/resources/adminuser.ts @@ -96,14 +96,6 @@ export default { resourceId: 'adminuser', } }, - { - name: "cars", - type: AdminForthDataTypes.STRING, - foreignResource: { - resourceId: 'cars_sl', - searchableFields: ['model'] - } - }, { name: "avatar", type: AdminForthDataTypes.STRING, From f8a2b472ad8e043b0478790fd1e75f6bd8d28f4a Mon Sep 17 00:00:00 2001 From: Vitalii Kulyk Date: Mon, 20 Apr 2026 14:03:16 +0300 Subject: [PATCH 6/6] fix: update action type in handleActionClick function for consistency --- adminforth/spa/src/components/ThreeDotsMenu.vue | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/adminforth/spa/src/components/ThreeDotsMenu.vue b/adminforth/spa/src/components/ThreeDotsMenu.vue index 7a7030b4c..9ac7bd855 100644 --- a/adminforth/spa/src/components/ThreeDotsMenu.vue +++ b/adminforth/spa/src/components/ThreeDotsMenu.vue @@ -103,7 +103,6 @@ import { useRoute, useRouter } from 'vue-router'; import CallActionWrapper from '@/components/CallActionWrapper.vue' import { ref, type ComponentPublicInstance, onMounted, onUnmounted } from 'vue'; import type { AdminForthActionFront, AdminForthBulkActionFront, AdminForthComponentDeclarationFull } from '@/types/Common'; -import type { AdminForthActionInput } from '@/types/Back'; import { Spinner } from '@/afcl'; const { list, alert} = useAdminforth(); @@ -137,7 +136,7 @@ function setComponentRef(el: ComponentPublicInstance | null, index: number) { } } -async function handleActionClick(action: AdminForthActionInput, payload: any) { +async function handleActionClick(action: AdminForthActionFront, payload: any) { list.closeThreeDotsDropdown(); await executeCustomAction({ actionId: action.id,