@@ -26,7 +26,7 @@ import { encodeRecordId, isCompositePrimaryKey, primaryKeyColumnNames } from './
2626
2727import { afLogger } from "./logger.js" ;
2828
29- import { ADMINFORTH_VERSION , listify , md5hash , getLoginPromptHTML , hookResponseError , parseLooseJson , RateLimiter } from './utils.js' ;
29+ import { ADMINFORTH_VERSION , listify , md5hash , getLoginPromptHTML , hookResponseError , parseLooseJson , RateLimiter , checkShowIf } from './utils.js' ;
3030
3131import AdminForthAuth from "../auth.js" ;
3232import { ActionCheckSource , AdminForthActionFront , AdminForthConfigMenuItem , AdminForthDataTypes , AdminForthFilterOperators , AdminForthResourceColumnInputCommon , AdminForthResourceFrontend , AdminForthResourcePages ,
@@ -37,6 +37,7 @@ import { ActionCheckSource, AdminForthActionFront, AdminForthConfigMenuItem, Adm
3737 ShowInResolved } from "../types/Common.js" ;
3838import { filtersTools } from "../modules/filtersTools.js" ;
3939import { normalizeColumnValue } from './columnValueNormalizer.js' ;
40+ import { isEmptyColumnValue , runColumnValidators } from './columnValueValidator.js' ;
4041
4142
4243async function resolveBoolOrFn (
@@ -127,16 +128,6 @@ const actionIdentifierSchema: AnySchemaObject = {
127128 ] ,
128129} ;
129130
130- const namedColumnSchema : AnySchemaObject = {
131- title : 'AdminForthNamedColumn' ,
132- type : 'object' ,
133- required : [ 'name' ] ,
134- properties : {
135- name : { type : 'string' } ,
136- } ,
137- additionalProperties : true ,
138- } ;
139-
140131const validationResultSchema : AnySchemaObject = {
141132 title : 'AdminForthValidationResult' ,
142133 type : 'object' ,
@@ -489,14 +480,10 @@ const getMinMaxForColumnsResponseSchema: AnySchemaObject = createErrorOrSuccessS
489480
490481const createRecordRequestSchema : AnySchemaObject = {
491482 type : 'object' ,
492- required : [ 'resourceId' , 'record' , 'requiredColumnsToSkip' ] ,
483+ required : [ 'resourceId' , 'record' ] ,
493484 properties : {
494485 resourceId : { type : 'string' } ,
495486 record : genericObjectSchema ,
496- requiredColumnsToSkip : {
497- type : 'array' ,
498- items : namedColumnSchema ,
499- } ,
500487 meta : genericObjectSchema ,
501488 } ,
502489 additionalProperties : true ,
@@ -2346,19 +2333,24 @@ export default class AdminForthRestAPI implements IAdminForthRestAPI {
23462333 return { error } ;
23472334 }
23482335
2349- const { record, requiredColumnsToSkip } = body ;
2336+ const { record } = body ;
2337+
2338+ const ctxCreate = {
2339+ adminUser,
2340+ resource,
2341+ meta : { requestBody : body } ,
2342+ source : ActionCheckSource . CreateRequest ,
2343+ adminforth : this . adminforth ,
2344+ } ;
23502345
2351- // todo if showIn.create is function, code below will be buggy (will not detect required fact)
23522346 for ( const column of resource . columns ) {
23532347 if (
2354- ( column . required as { create ?: boolean , edit ?: boolean } ) ?. create &&
2355- record [ column . name ] === undefined &&
2356- column . showIn . create
2348+ column . required . create &&
2349+ isEmptyColumnValue ( column , record [ column . name ] ) &&
2350+ await isShown ( column , 'create' , ctxCreate ) &&
2351+ checkShowIf ( column , record , resource . columns )
23572352 ) {
2358- const shouldWeSkipColumn = requiredColumnsToSkip . find ( reqColumnToSkip => reqColumnToSkip . name === column . name ) ;
2359- if ( ! shouldWeSkipColumn ) {
2360- return { error : `Column '${ column . name } ' is required` , ok : false } ;
2361- }
2353+ return { error : `Column '${ column . name } ' is required` , ok : false } ;
23622354 }
23632355 }
23642356
@@ -2385,26 +2377,6 @@ export default class AdminForthRestAPI implements IAdminForthRestAPI {
23852377 }
23862378 }
23872379
2388- const ctxCreate = {
2389- adminUser,
2390- resource,
2391- meta : { requestBody : body } ,
2392- source : ActionCheckSource . CreateRequest ,
2393- adminforth : this . adminforth ,
2394- } ;
2395-
2396- for ( const column of resource . columns ) {
2397- if ( ( column . required as { create ?: boolean } ) ?. create ) {
2398- const shown = await isShown ( column , 'create' , ctxCreate ) ;
2399- const shouldWeSkipColumn = requiredColumnsToSkip . find ( reqColumnToSkip => reqColumnToSkip . name === column . name ) ;
2400- if ( ! shouldWeSkipColumn ) {
2401- if ( shown && record [ column . name ] === undefined ) {
2402- return { error : `Column '${ column . name } ' is required` , ok : false } ;
2403- }
2404- }
2405- }
2406- }
2407-
24082380 for ( const column of resource . columns ) {
24092381 const fieldName = column . name ;
24102382 if ( fieldName in record ) {
@@ -2600,6 +2572,15 @@ export default class AdminForthRestAPI implements IAdminForthRestAPI {
26002572 ok : false ,
26012573 } ;
26022574 }
2575+
2576+ if (
2577+ column . required . edit &&
2578+ shown &&
2579+ isEmptyColumnValue ( column , record [ fieldName ] ) &&
2580+ checkShowIf ( column , { ...oldRecord , ...record } , resource . columns )
2581+ ) {
2582+ return { error : `Column '${ fieldName } ' is required` , ok : false } ;
2583+ }
26032584 }
26042585 }
26052586 // for polymorphic foreign resources, we need to find out the value for polymorphicOn column
@@ -2888,17 +2869,9 @@ export default class AdminForthRestAPI implements IAdminForthRestAPI {
28882869 const columnConfig = resource . columns . find ( ( c ) => c . name === col . name ) ;
28892870 if ( columnConfig && columnConfig . validation ) {
28902871 customColumnValidatorsFunctions . push ( async ( ) => {
2891- for ( const val of columnConfig . validation ) {
2892- if ( val . validator ) {
2893- const result = await val . validator ( col . value , record , this . adminforth ) ;
2894- if ( typeof result === 'object' && result . isValid === false ) {
2895- validationResults [ col . name ] = {
2896- isValid : result . isValid ,
2897- message : result . message ,
2898- }
2899- break ;
2900- }
2901- }
2872+ const failedResult = await runColumnValidators ( columnConfig , col . value , record , this . adminforth ) ;
2873+ if ( failedResult ) {
2874+ validationResults [ col . name ] = failedResult ;
29022875 }
29032876 } )
29042877 }
0 commit comments