-
Notifications
You must be signed in to change notification settings - Fork 18
Dynamic filter #231
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: next
Are you sure you want to change the base?
Dynamic filter #231
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -658,6 +658,44 @@ export default class ConfigValidator implements IConfigValidator { | |
} | ||
} | ||
|
||
if (col.foreignResource.searchableFields) { | ||
const searchableFields = Array.isArray(col.foreignResource.searchableFields) | ||
? col.foreignResource.searchableFields | ||
: [col.foreignResource.searchableFields]; | ||
|
||
searchableFields.forEach((fieldName) => { | ||
if (typeof fieldName !== 'string') { | ||
errors.push(`Resource "${res.resourceId}" column "${col.name}" foreignResource.searchableFields must contain only strings`); | ||
return; | ||
} | ||
|
||
if (col.foreignResource.resourceId) { | ||
const targetResource = this.inputConfig.resources.find((r) => r.resourceId === col.foreignResource.resourceId || r.table === col.foreignResource.resourceId); | ||
if (targetResource) { | ||
const targetColumn = targetResource.columns.find((targetCol) => targetCol.name === fieldName); | ||
if (!targetColumn) { | ||
const similar = suggestIfTypo(targetResource.columns.map((c) => c.name), fieldName); | ||
errors.push(`Resource "${res.resourceId}" column "${col.name}" foreignResource.searchableFields contains field "${fieldName}" which does not exist in target resource "${targetResource.resourceId || targetResource.table}". ${similar ? `Did you mean "${similar}"?` : ''}`); | ||
} | ||
} | ||
} else if (col.foreignResource.polymorphicResources) { | ||
// For polymorphic resources, check all possible target resources | ||
for (const pr of col.foreignResource.polymorphicResources) { | ||
if (pr.resourceId) { | ||
const targetResource = this.inputConfig.resources.find((r) => r.resourceId === pr.resourceId || r.table === pr.resourceId); | ||
if (targetResource) { | ||
const hasField = targetResource.columns.some((targetCol) => targetCol.name === fieldName); | ||
if (!hasField) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. so if at least one resource will not have column it will crash. This should be changed to - if there are no resources which have this column then crash. if poly has 2 resources:
So when applying poly search (later in code) - extract subset of this searchable fields which exist in resource and use only them in search with disjunction way |
||
const similar = suggestIfTypo(targetResource.columns.map((c) => c.name), fieldName); | ||
errors.push(`Resource "${res.resourceId}" column "${col.name}" foreignResource.searchableFields contains field "${fieldName}" which does not exist in polymorphic target resource "${pr.resourceId}". ${similar ? `Did you mean "${similar}"?` : ''}`); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
}); | ||
} | ||
|
||
if (col.foreignResource.unsetLabel) { | ||
if (typeof col.foreignResource.unsetLabel !== 'string') { | ||
errors.push(`Resource "${res.resourceId}" column "${col.name}" has foreignResource unsetLabel which is not a string`); | ||
|
@@ -666,6 +704,12 @@ export default class ConfigValidator implements IConfigValidator { | |
// set default unset label | ||
col.foreignResource.unsetLabel = 'Unset'; | ||
} | ||
|
||
// Set default searchIsCaseSensitive | ||
if (col.foreignResource.searchIsCaseSensitive === undefined) { | ||
col.foreignResource.searchIsCaseSensitive = false; | ||
} | ||
|
||
const befHook = col.foreignResource.hooks?.dropdownList?.beforeDatasourceRequest; | ||
if (befHook) { | ||
if (!Array.isArray(befHook)) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -834,7 +834,7 @@ export default class AdminForthRestAPI implements IAdminForthRestAPI { | |
method: 'POST', | ||
path: '/get_resource_foreign_data', | ||
handler: async ({ body, adminUser, headers, query, cookies, requestUrl }) => { | ||
const { resourceId, column } = body; | ||
const { resourceId, column, search } = body; | ||
if (!this.adminforth.statuses.dbDiscover) { | ||
return { error: 'Database discovery not started' }; | ||
} | ||
|
@@ -905,6 +905,34 @@ export default class AdminForthRestAPI implements IAdminForthRestAPI { | |
throw new Error(`Wrong filter object value: ${JSON.stringify(filters)}`); | ||
} | ||
} | ||
|
||
if (search && search.trim() && columnConfig.foreignResource.searchableFields) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think poly case is not implemented here at all - it should do parallel queries There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. or probably you can do it on frontend (later) - should be possible also, maybe even better |
||
const searchableFields = Array.isArray(columnConfig.foreignResource.searchableFields) | ||
? columnConfig.foreignResource.searchableFields | ||
: [columnConfig.foreignResource.searchableFields]; | ||
|
||
const searchOperator = columnConfig.foreignResource.searchIsCaseSensitive | ||
? AdminForthFilterOperators.LIKE | ||
: AdminForthFilterOperators.ILIKE; | ||
|
||
const searchFilters = searchableFields.map((fieldName) => { | ||
const filter = { | ||
field: fieldName, | ||
operator: searchOperator, | ||
value: `%${search.trim()}%`, | ||
}; | ||
return filter; | ||
}); | ||
|
||
if (searchFilters.length > 1) { | ||
normalizedFilters.subFilters.push({ | ||
operator: AdminForthFilterOperators.OR, | ||
subFilters: searchFilters, | ||
}); | ||
} else if (searchFilters.length === 1) { | ||
normalizedFilters.subFilters.push(searchFilters[0]); | ||
} | ||
} | ||
const dbDataItems = await this.adminforth.connectors[targetResource.dataSource].getData({ | ||
resource: targetResource, | ||
limit, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@SerVitasik or text at least