Skip to content

Commit 5a13112

Browse files
committed
Merge branch 'next' of https://github.com/devforth/adminforth into next
2 parents 71d113f + 1265db8 commit 5a13112

File tree

7 files changed

+49
-59
lines changed

7 files changed

+49
-59
lines changed

adminforth/documentation/docs/tutorial/03-Customization/06-customPages.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,11 +306,14 @@ Open `index.ts` file and add the following code *BEFORE* `admin.express.serve(`
306306
307307
```ts title="/index.ts"
308308
309+
import type { IAdminUserExpressRequest } from 'adminforth';
310+
import express from 'express';
311+
309312
....
310313
311314
app.get(`${ADMIN_BASE_URL}/api/dashboard/`,
312315
admin.express.authorize(
313-
async (req:any, res:any) => {
316+
async (req:IAdminUserExpressRequest, res: express.Response) => {
314317
const days = req.body.days || 7;
315318
const apartsByDays = admin.resource('aparts').dataConnector.client.prepare(
316319
`SELECT

adminforth/documentation/docs/tutorial/03-Customization/08-pageInjections.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,14 @@ Now create file `ApartsPie.vue` in the `custom` folder of your project:
9898
Also we have to add an Api to get percentages:
9999
100100
```ts title="./index.ts"
101+
import type { IAdminUserExpressRequest } from 'adminforth';
102+
import express from 'express';
103+
104+
....
105+
101106
app.get(`${ADMIN_BASE_URL}/api/aparts-by-room-percentages/`,
102107
admin.express.authorize(
103-
async (req, res) => {
108+
async (req: IAdminUserExpressRequest, res: express.Response) => {
104109
const roomPercentages = await admin.resource('aparts').dataConnector.client.prepare(
105110
`SELECT
106111
number_of_rooms,

adminforth/documentation/docs/tutorial/07-Plugins/01-AuditLog.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,10 +160,14 @@ Audit log is able to catch only standard actions like `create`, `update`, `delet
160160
If you have a custom, self coded actions in your API, you can log them by calling `logCustomAction` method of `AuditLogPlugin` instance:
161161
162162
```ts title="./resources/index.ts"
163+
import type { IAdminUserExpressRequest, ITranslateExpressRequest } from 'adminforth';
164+
import express from 'express';
165+
166+
....
163167

164168
app.get(`${ADMIN_BASE_URL}/api/dashboard/`,
165169
admin.express.authorize(
166-
async (req, res) => {
170+
async (req: IAdminUserExpressRequest, res: express.Response) => {
167171

168172
admin.getPluginByClassName<AuditLogPlugin>('AuditLogPlugin').logCustomAction({
169173
resourceId: 'aparts',

adminforth/documentation/docs/tutorial/07-Plugins/10-i18n.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,10 +425,15 @@ onMounted(async () => {
425425
And on the backend side you can use tr function to translate the string:
426426
427427
```ts title="./index.ts"
428+
import type { IAdminUserExpressRequest, ITranslateExpressRequest } from 'adminforth';
429+
import express from 'express';
430+
431+
....
432+
428433
app.get(`${ADMIN_BASE_URL}/api/greeting`,
429434
admin.express.authorize(
430435
admin.express.translatable(
431-
async (req, res) => {
436+
async (req: IAdminUserExpressRequest & ITranslateExpressRequest, res: express.Response) => {
432437
res.json({
433438
text: await req.tr('Welcome, {name}', 'customApis', { name: req.adminUser.username }),
434439
});

adminforth/modules/restApi.ts

Lines changed: 6 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,10 @@ export async function interpretResource(
2929
meta: any,
3030
source: ActionCheckSource,
3131
adminforth: IAdminForth
32-
): Promise<{ allowedActions: AllowedActionsResolved; visibleColumns: Record<string, boolean> }> {
32+
): Promise<{allowedActions: AllowedActionsResolved}> {
3333
if (process.env.HEAVY_DEBUG) {
3434
console.log('🪲Interpreting resource', resource.resourceId, source, 'adminUser', adminUser);
3535
}
36-
3736
const allowedActions = {} as AllowedActionsResolved;
3837

3938
// we need to compute only allowed actions for this source:
@@ -62,6 +61,8 @@ export async function interpretResource(
6261
allowedActions[key] = false;
6362
return;
6463
}
64+
65+
// if callable then call
6566
if (typeof value === 'function') {
6667
allowedActions[key] = await value({ adminUser, resource, meta, source, adminforth });
6768
} else {
@@ -70,47 +71,7 @@ export async function interpretResource(
7071
})
7172
);
7273

73-
const resolveVisible = async (val: any): Promise<boolean> => {
74-
if (typeof val === 'boolean') return val;
75-
if (typeof val === 'function') {
76-
const r = val({ adminUser, resource, meta, source, adminforth });
77-
return r instanceof Promise ? await r : !!r;
78-
}
79-
return true;
80-
};
81-
82-
const pageMap = {
83-
[ActionCheckSource.ListRequest]: 'list',
84-
[ActionCheckSource.ShowRequest]: 'show',
85-
[ActionCheckSource.EditLoadRequest]: 'edit',
86-
} as const;
87-
88-
const page = pageMap[source as keyof typeof pageMap] as ('list'|'show'|'edit') | undefined;
89-
90-
if (!page) {
91-
return { allowedActions, visibleColumns: {} };
92-
}
93-
94-
const isColumnVisible = async (col: any): Promise<boolean> => {
95-
const si = col.showIn;
96-
if (!si) return true;
97-
98-
if (Array.isArray(si)) {
99-
return si.includes('all') || si.includes(page);
100-
}
101-
102-
if (si[page] !== undefined) return await resolveVisible(si[page]);
103-
if (si.all !== undefined) return await resolveVisible(si.all);
104-
return true;
105-
};
106-
107-
const visibleColumnsEntries = await Promise.all(
108-
resource.columns.map(async (col) => [col.name, await isColumnVisible(col)] as const)
109-
);
110-
111-
const visibleColumns = Object.fromEntries(visibleColumnsEntries) as Record<string, boolean>;
112-
113-
return { allowedActions, visibleColumns };
74+
return { allowedActions };
11475
}
11576

11677
export default class AdminForthRestAPI implements IAdminForthRestAPI {
@@ -641,7 +602,7 @@ export default class AdminForthRestAPI implements IAdminForthRestAPI {
641602
meta.pk = body.filters.find((f) => f.field === resource.columns.find((col) => col.primaryKey).name)?.value;
642603
}
643604

644-
const { allowedActions, visibleColumns } = await interpretResource(
605+
const { allowedActions } = await interpretResource(
645606
adminUser,
646607
resource,
647608
meta,
@@ -844,12 +805,7 @@ export default class AdminForthRestAPI implements IAdminForthRestAPI {
844805
// remove all columns which are not defined in resources, or defined but backendOnly
845806
data.data.forEach((item) => {
846807
Object.keys(item).forEach((key) => {
847-
const isPk = pkField && key === pkField;
848-
const isUnknown = !resource.columns.find((col) => col.name === key);
849-
const isBackendOnly = resource.columns.find((col) => col.name === key && col.backendOnly);
850-
const isHiddenByACL = visibleColumns?.[key] === false;
851-
852-
if (isUnknown || isBackendOnly || (isHiddenByACL && !isPk)) {
808+
if (!resource.columns.find((col) => col.name === key) || resource.columns.find((col) => col.name === key && col.backendOnly)) {
853809
delete item[key];
854810
}
855811
})

adminforth/types/Back.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { Express } from 'express';
1+
import type { Express, Request } from 'express';
22
import type { Writable } from 'stream';
33

44
import { ActionCheckSource, AdminForthFilterOperators, AdminForthSortDirections, AllowedActionsEnum,
@@ -105,6 +105,23 @@ export interface IExpressHttpServer extends IHttpServer {
105105
authorize(callable: Function): void;
106106
}
107107

108+
export interface ITranslateFunction {
109+
(
110+
msg: string,
111+
category: string,
112+
params: any,
113+
pluralizationNumber?: number
114+
): Promise<string>;
115+
}
116+
117+
// Omit <Request, 'param'> is used to remove 'param' method from Request type for correct docs generation
118+
export interface IAdminUserExpressRequest extends Omit<Request, 'param'> {
119+
adminUser: AdminUser;
120+
}
121+
122+
export interface ITranslateExpressRequest extends Omit<Request, 'param'> {
123+
tr: ITranslateFunction;
124+
}
108125

109126
export interface IAdminForthSingleFilter {
110127
field?: string;

dev-demo/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import betterSqlite3 from 'better-sqlite3';
22
import express from 'express';
33
import AdminForth, { AdminUser, Filters } from '../adminforth/index.js';
4-
4+
import type { IAdminUserExpressRequest, ITranslateExpressRequest } from 'adminforth';
55
import clicksResource from './resources/clicks.js';
66
import apartmentsResource from './resources/apartments.js';
77
import apartmentBuyersResource from './resources/apartment_buyers.js';
@@ -361,7 +361,7 @@ const port = process.env.PORT || 3000;
361361
app.get(
362362
'/api/testtest/',
363363
admin.express.authorize(
364-
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
364+
async (req: IAdminUserExpressRequest, res: express.Response, next: express.NextFunction) => {
365365
res.json({ ok: true, data: [1,2,3], adminUser: req.adminUser });
366366
}
367367
)
@@ -370,7 +370,7 @@ app.get(
370370
app.get(`${ADMIN_BASE_URL}/api/dashboard/`,
371371
admin.express.authorize(
372372
admin.express.translatable(
373-
async (req: any, res: express.Response) => {
373+
async (req: IAdminUserExpressRequest & ITranslateExpressRequest, res: express.Response) => {
374374
const days = req.body.days || 7;
375375
const apartsByDays = await admin.resource('aparts').dataConnector.client.prepare(
376376
`SELECT
@@ -470,7 +470,7 @@ app.get(`${ADMIN_BASE_URL}/api/dashboard/`,
470470

471471
app.get(`${ADMIN_BASE_URL}/api/aparts-by-room-percentages/`,
472472
admin.express.authorize(
473-
async (req, res) => {
473+
async (req: IAdminUserExpressRequest, res: express.Response) => {
474474
const roomPercentages = await admin.resource('aparts').dataConnector.client.prepare(
475475
`SELECT
476476
number_of_rooms,

0 commit comments

Comments
 (0)