-
Notifications
You must be signed in to change notification settings - Fork 23
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
feat(bulk-import): adding sorting based on column in /imports #178
base: main
Are you sure you want to change the base?
feat(bulk-import): adding sorting based on column in /imports #178
Conversation
Changed Packages
|
54ca224
to
ba86c46
Compare
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.
Hi @its-mitesh-kumar, thanks for picking up also the backend work.
I added some comments, that IMHO we should remove the sorting in our backend, and add sorting params to the request calls for GitHub / Catalog API calls.
Let me know if I miss something and its not possible for some reason. And let the backend team and me know if you want continue with this.
export enum AddedRepositoryColumnNameEnum { | ||
repoName = 'repository.name', | ||
organizationUrl = 'repository.organization', | ||
repoUrl = 'repository.url', | ||
catalogInfoYamlLastUpdated = 'lastUpdate', | ||
catalogInfoYamlStatus = 'status', | ||
} | ||
export enum SortingOrderEnum { | ||
ASC = 'asc', | ||
DESC = 'desc', | ||
} |
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.
Please respect the convention in this file
- and add empty lines between each type definition
- and it looks like enum keys here are all UPPER_CASE
// sorting the output to make it deterministic and easy to navigate in the UI | ||
sortImports(imports); | ||
|
||
if (sortColumn) { | ||
sortImports(imports, sortColumn, sortOrder); | ||
} |
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.
Are we always fetching ALL elements in the backend?
And guess that we are and should not do that. So this sort function will only sort the current window (fetched page).
Instead of that we should pass the sorting to the backend calls like GitHub and the catalog API and remove the sorting from our backend.
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.
Yes, it would be the best if we could sort and paginate at the Github side. Unfortunately, for /imports
endpoint, I believe we are fetching all Catalog locations and then filtering those reachable with GH integrations. @rm3l might have valuable insights into the reasoning behind this solution and whether we can approach this more effectively. Maybe we can adjust filterLocationsAccessibleFromIntegrations here.
When fetching Catalog locations, pageNumber
and pageSize
are passed as params but not really used there, since we don't know which ones are actually reachable GH integrations. Maybe the best approach would be to switch stuff around and first fetch GH integrations, maybe it would help performance.
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.
Indeed, IIRC, the /imports
endpoint fetches Catalog locations first and only keeps those reachable from the configured GH integrations. Initially, it was querying GH first, but this was causing major performance issues, as reported in https://issues.redhat.com/browse/RHIDP-3680
Also, note that the imports may be coming from different sources (app-config, repos registered manually in Backstage, auto-discovery, ...), and the user may have configured several GH integrations (like different GH apps installed in multiple orgs).
That's essentially why the backend needed to aggregate such various sources to properly implement not only sorting, but also search and pagination, and return what the user is requesting.
But I guess pagination should help reduce the number of data fetched and iterated over.
That being said, open to better suggestions.
function sortImports( | ||
imports: Components.Schemas.Import[], | ||
sortColumn: string = 'repository.name', | ||
sortOrder: string = SortingOrderEnum.ASC, | ||
) { | ||
imports.sort((a, b) => { | ||
if (a.repository?.name === undefined && b.repository?.name === undefined) { | ||
return 0; | ||
} | ||
if (a.repository?.name === undefined) { | ||
return -1; | ||
} | ||
if (b.repository?.name === undefined) { | ||
return 1; | ||
} | ||
return a.repository.name.localeCompare(b.repository.name); | ||
const value1 = getNestedValue(a, sortColumn); | ||
const value2 = getNestedValue(b, sortColumn); | ||
// Handle cases where values are undefined | ||
if (value1 === undefined && value2 === undefined) return 0; | ||
if (value1 === undefined) return SortingOrderEnum.ASC ? -1 : 1; | ||
if (value2 === undefined) return SortingOrderEnum.ASC ? 1 : -1; | ||
// Compare values based on sort order | ||
return SortingOrderEnum.ASC === sortOrder | ||
? value1.localeCompare(value2) | ||
: value2.localeCompare(value1); | ||
}); | ||
} |
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.
We should eliminate this and add the sorting parameter to the GitHub / Catalog API calls.
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.
Github APIs not supporting sorting on these params .
export function getNestedValue<T>(obj: T, path: string): any { | ||
return path | ||
.split('.') | ||
.reduce( | ||
(acc, key) => | ||
acc && (acc as Record<string, any>)[key] | ||
? (acc as Record<string, any>)[key] | ||
: undefined, | ||
obj, | ||
); | ||
} | ||
export enum SortingOrderEnum { | ||
ASC = 'asc', | ||
DESC = 'desc', | ||
} |
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.
We should eliminate this and add the sorting parameter to the GitHub / Catalog API calls.
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.
Github APIs not supporting sorting on these params .
sortColumnQueryParam: | ||
in: query | ||
name: sortColumn | ||
description: The name of the column to sort by | ||
required: false | ||
schema: | ||
type: string |
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.
It would be amazing if you could add for sortColumnQueryParam
enum values with description of what each value means and then reuse the generated types.
export enum SortingOrderEnum { | ||
ASC = 'asc', | ||
DESC = 'desc', | ||
} |
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.
You have defined SortingOrderEnum
also in types, ultimately it would be the best to reuse types generated in openapi.d.ts so we are not out of sync.
ba86c46
to
ea7ffa3
Compare
@christoph-jerolimov @dzemanov I have resolved the comments , Please re-review it |
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.
Tested with all sort values, on the backend and frontend. Works as expected except for when sortColumn
is not specified. Please run prettier
to fix failing tests :).
export enum AddedRepositoryColumnNameEnum { | ||
repoName = 'repository.name', // because of property name | ||
repositoryName = 'repository.name', | ||
organizationUrl = 'repository.organization', | ||
repoUrl = 'repository.url', | ||
catalogInfoYamlLastUpdated = 'lastUpdate', | ||
catalogInfoYamlStatus = 'status', | ||
} |
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.
Maybe it would be good to unify this and not repeat values. If repoName
is needed, you can remove repositoryName
and instead always use repoName
.
export enum AddedRepositoryColumnNameEnum { | |
repoName = 'repository.name', // because of property name | |
repositoryName = 'repository.name', | |
organizationUrl = 'repository.organization', | |
repoUrl = 'repository.url', | |
catalogInfoYamlLastUpdated = 'lastUpdate', | |
catalogInfoYamlStatus = 'status', | |
} | |
export enum AddedRepositoryColumnNameEnum { | |
repoName = 'repository.name', | |
organizationUrl = 'repository.organization', | |
repoUrl = 'repository.url', | |
catalogInfoYamlLastUpdated = 'lastUpdate', | |
catalogInfoYamlStatus = 'status', | |
} |
const sortColumn = queryParams?.sortColumn; | ||
const sortOrder = queryParams?.sortOrder; |
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.
You have defined in openapi.yaml
both sortOrderQueryParam
and sortColumnQueryParam
to have default values if user does not provide them. But they are not used (they are not set automatically to default if undefined).
So either remove default values - in that case, we need to handle invalid option when user does not provide both of these parameters. Or I would suggest adding them here and then remove the change with if (sortColumn)
workspaces/bulk-import/plugins/bulk-import-backend/src/schema/openapi.yaml
Outdated
Show resolved
Hide resolved
Also, please add changeset. |
@@ -45,18 +49,31 @@ type FindAllImportsResponse = | |||
| Components.Schemas.Import[] | |||
| Components.Schemas.ImportJobListV2; | |||
|
|||
function sortImports(imports: Components.Schemas.Import[]) { | |||
function sortImports( |
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.
Could you add some tests in the backend for this feature? At least a few unit tests for this function. Or, better, some more complete tests in https://github.com/redhat-developer/rhdh-plugins/blob/main/workspaces/bulk-import/plugins/bulk-import-backend/src/service/handlers/import/bulkImports.test.ts and/or https://github.com/redhat-developer/rhdh-plugins/blob/main/workspaces/bulk-import/plugins/bulk-import-backend/src/service/handlers/import/imports.test.ts
e19fab3
to
c2cff41
Compare
…openapi.yaml Co-authored-by: Dominika Zemanovicova <[email protected]>
Resolves : https://issues.redhat.com/browse/RHIDP-5295