Skip to content

Commit

Permalink
feat(bulk-import): adding sorting based on column in /imports (#178)
Browse files Browse the repository at this point in the history
* feat(bulk-import): adding sorting based on column in /imports

* feat(bul-import): fixing typescript error

* feat(bulk-import) : resolving comments

* feat(bulk-import): adding changeset

* feat(bulk-import): handling empty column name

* feat(bulk-import): adding unit test

* feat(bulk-import): fix typescript error

* feat(bulk-import): remove '' to  be passed as columnName or orderBy

* feat(bulk-import): remove '' from unit test

* feat(bulk-import): remove extra column name key from enum

* Update workspaces/bulk-import/plugins/bulk-import/src/types/types.ts

Co-authored-by: Dominika Zemanovicova <[email protected]>

* feat(bulk-import): updatin changeset file

---------

Co-authored-by: Dominika Zemanovicova <[email protected]>
  • Loading branch information
its-mitesh-kumar and dzemanov authored Jan 22, 2025
1 parent f3faa85 commit b47ad99
Show file tree
Hide file tree
Showing 17 changed files with 398 additions and 51 deletions.
6 changes: 6 additions & 0 deletions workspaces/bulk-import/.changeset/four-buses-glow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@red-hat-developer-hub/backstage-plugin-bulk-import-backend': patch
'@red-hat-developer-hub/backstage-plugin-bulk-import': patch
---

Implemented Server Side Sorting for `GET /imports`

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,20 @@ declare namespace Components {
export type SizePerIntegrationQueryParam = number;
export type SizePerIntegrationQueryParamDeprecated = number;
export type SizeQueryParam = number;
export type SortColumnQueryParam =
| 'repository.name'
| 'repository.organization'
| 'repository.url'
| 'lastUpdate'
| 'status';
export type SortOrderQueryParam = 'asc' | 'desc';
}
export interface QueryParameters {
pagePerIntegrationQueryParam?: Parameters.PagePerIntegrationQueryParam;
sizePerIntegrationQueryParam?: Parameters.SizePerIntegrationQueryParam;
pagePerIntegrationQueryParamDeprecated?: Parameters.PagePerIntegrationQueryParamDeprecated;
sortColumnQueryParam?: Parameters.SortColumnQueryParam;
sortOrderQueryParam?: Parameters.SortOrderQueryParam;
sizePerIntegrationQueryParamDeprecated?: Parameters.SizePerIntegrationQueryParamDeprecated;
searchQueryParam?: Parameters.SearchQueryParam;
pageQueryParam?: Parameters.PageQueryParam;
Expand Down Expand Up @@ -328,12 +337,21 @@ declare namespace Paths {
export type Search = string;
export type Size = number;
export type SizePerIntegration = number;
export type SortColumn =
| 'repository.name'
| 'repository.organization'
| 'repository.url'
| 'lastUpdate'
| 'status';
export type SortOrder = 'asc' | 'desc';
}
export interface QueryParameters {
pagePerIntegration?: Parameters.PagePerIntegration;
sizePerIntegration?: Parameters.SizePerIntegration;
page?: Parameters.Page;
size?: Parameters.Size;
sortOrder?: Parameters.SortOrder;
sortColumn?: Parameters.SortColumn;
search?: Parameters.Search;
}
namespace Responses {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,12 @@ const OPENAPI = `
{
"$ref": "#/components/parameters/sizeQueryParam"
},
{
"$ref": "#/components/parameters/sortOrderQueryParam"
},
{
"$ref": "#/components/parameters/sortColumnQueryParam"
},
{
"$ref": "#/components/parameters/searchQueryParam"
}
Expand Down Expand Up @@ -562,6 +568,36 @@ const OPENAPI = `
"default": 1
}
},
"sortColumnQueryParam": {
"in": "query",
"name": "sortColumn",
"description": "The allowed values for sorting columns:\\n- repository.name: Sort by repository name.\\n- repository.organization: Sort by organization URL.\\n- repository.url: Sort by repository URL.\\n- lastUpdate: Sort by the last time the catalog-info.yaml was updated.\\n- status: Sort by the status of the catalog-info.yaml.\\n",
"required": false,
"schema": {
"enum": [
"repository.name",
"repository.organization",
"repository.url",
"lastUpdate",
"status"
],
"default": "repository.name"
}
},
"sortOrderQueryParam": {
"in": "query",
"name": "sortOrder",
"description": "The order of sorting asc for ascending or desc for descending",
"required": false,
"schema": {
"type": "string",
"enum": [
"asc",
"desc"
],
"default": "asc"
}
},
"sizePerIntegrationQueryParamDeprecated": {
"in": "query",
"name": "sizePerIntegration",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@
export * from './auth';
export * from './loggingUtils';
export * from './pagination';
export * from './utils';
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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,
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,8 @@ paths:
- $ref: '#/components/parameters/sizePerIntegrationQueryParamDeprecated'
- $ref: '#/components/parameters/pageQueryParam'
- $ref: '#/components/parameters/sizeQueryParam'

- $ref: '#/components/parameters/sortOrderQueryParam'
- $ref: '#/components/parameters/sortColumnQueryParam'
- $ref: '#/components/parameters/searchQueryParam'

responses:
Expand Down Expand Up @@ -360,6 +361,38 @@ components:
schema:
type: integer
default: 1
sortColumnQueryParam:
in: query
name: sortColumn
description: |
The allowed values for sorting columns:
- `repository.name`: Sort by repository name.
- `repository.organization`: Sort by organization URL.
- `repository.url`: Sort by repository URL.
- `lastUpdate`: Sort by the last time the catalog-info.yaml was updated.
- `status`: Sort by the status of the catalog-info.yaml.
required: false
schema:
enum:
- repository.name
- repository.organization
- repository.url
- lastUpdate
- status
default: repository.name

sortOrderQueryParam:
in: query
name: sortOrder
description: The order of sorting asc for ascending or desc for descending
required: false
schema:
type: string
enum:
- asc
- desc
default: asc

sizePerIntegrationQueryParamDeprecated:
in: query
name: sizePerIntegration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type { Components } from '../../generated/openapi';

export const DefaultPageNumber = 1;
export const DefaultPageSize = 20;

export const DefaultSortColumn: Components.Parameters.SortColumnQueryParam =
'repository.name';
export const DefaultSortOrder: Components.Parameters.SortOrderQueryParam =
'asc';

export interface HandlerResponse<ResponseBody = any> {
statusCode: number;
responseBody?: ResponseBody;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,119 @@ describe('bulkimports.ts unit tests', () => {
}
expect(resp.responseBody).toEqual(expectedResponse);

// Unit test for sort if nothing is provided sorting should be based on name in asc order
resp = await findAllImports(
{
logger,
config,
githubApiService: mockGithubApiService,
catalogHttpClient: mockCatalogHttpClient,
},
{
apiVersion,
},
{
pageNumber: 1,
pageSize: 6,
},
);
const sortedNames =
apiVersion === 'v2'
? (
resp?.responseBody as {
imports: { repository: { name: any } }[];
}
)?.imports?.map(importObj => importObj.repository.name)
: (resp?.responseBody as { repository: { name: any } }[])?.map(
importObj => importObj.repository.name,
);
let expectedSortedArray = [
'my-repo-11',
'my-repo-123',
'my-repo-21',
'my-repo-22',
'my-repo-31',
'my-repo-32',
];
expect(sortedNames).toEqual(expectedSortedArray);

// sorting based on organization in asc order
resp = await findAllImports(
{
logger,
config,
githubApiService: mockGithubApiService,
catalogHttpClient: mockCatalogHttpClient,
},
{
apiVersion,
},
{
pageNumber: 1,
pageSize: 6,
sortColumn: 'repository.organization',
sortOrder: 'asc',
},
);

let sortedOrganization =
apiVersion === 'v2'
? (
resp?.responseBody as {
imports: { repository: { organization: any } }[];
}
)?.imports?.map(importObj => importObj.repository.organization)
: (
resp?.responseBody as { repository: { organization: any } }[]
)?.map(importObj => importObj.repository.organization);
expectedSortedArray = [
'my-org-1',
'my-org-2',
'my-org-2',
'my-org-3',
'my-org-3',
'my-user',
];
expect(sortedOrganization).toEqual(expectedSortedArray);
// sorting based on organization in desc order
resp = await findAllImports(
{
logger,
config,
githubApiService: mockGithubApiService,
catalogHttpClient: mockCatalogHttpClient,
},
{
apiVersion,
},
{
pageNumber: 1,
pageSize: 6,
sortColumn: 'repository.organization',
sortOrder: 'desc',
},
);

sortedOrganization =
apiVersion === 'v2'
? (
resp?.responseBody as {
imports: { repository: { organization: any } }[];
}
)?.imports?.map(importObj => importObj.repository.organization)
: (
resp?.responseBody as { repository: { organization: any } }[]
)?.map(importObj => importObj.repository.organization);
expectedSortedArray = [
'my-user',
'my-org-3',
'my-org-3',
'my-org-2',
'my-org-2',
'my-org-1',
];
expect(sortedOrganization).toEqual(expectedSortedArray);

// No data for this page
resp = await findAllImports(
{
Expand Down
Loading

0 comments on commit b47ad99

Please sign in to comment.