Skip to content

Commit 07ffa98

Browse files
authored
Merge pull request #302 from devforth/hide-columns-by-showIn
feat: filter returned fields based on column showIn visibility
2 parents c39ed72 + 2526a03 commit 07ffa98

File tree

1 file changed

+46
-6
lines changed

1 file changed

+46
-6
lines changed

adminforth/modules/restApi.ts

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

3839
// we need to compute only allowed actions for this source:
@@ -61,8 +62,6 @@ export async function interpretResource(
6162
allowedActions[key] = false;
6263
return;
6364
}
64-
65-
// if callable then call
6665
if (typeof value === 'function') {
6766
allowedActions[key] = await value({ adminUser, resource, meta, source, adminforth });
6867
} else {
@@ -71,7 +70,47 @@ export async function interpretResource(
7170
})
7271
);
7372

74-
return { allowedActions };
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 };
75114
}
76115

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

605-
const { allowedActions } = await interpretResource(
644+
const { allowedActions, visibleColumns } = await interpretResource(
606645
adminUser,
607646
resource,
608647
meta,
@@ -804,7 +843,8 @@ export default class AdminForthRestAPI implements IAdminForthRestAPI {
804843
// remove all columns which are not defined in resources, or defined but backendOnly
805844
data.data.forEach((item) => {
806845
Object.keys(item).forEach((key) => {
807-
if (!resource.columns.find((col) => col.name === key) || resource.columns.find((col) => col.name === key && col.backendOnly)) {
846+
console.log(visibleColumns?.[key], key);
847+
if (!resource.columns.find((col) => col.name === key) || resource.columns.find((col) => col.name === key && col.backendOnly) || visibleColumns?.[key] === false ) {
808848
delete item[key];
809849
}
810850
})

0 commit comments

Comments
 (0)